【unity实战】时间控制 昼夜交替 四季变化 天气变化效果

这篇具有很好参考价值的文章主要介绍了【unity实战】时间控制 昼夜交替 四季变化 天气变化效果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最终效果

【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

日期季节控制

public class TimeManager : MonoBehaviour
{
    public static TimeManager Instance { get; private set; }

    // 定义一个事件,在每天过去时触发
    public UnityEvent OnDayPass = new UnityEvent();

    // 季节枚举类型
    public enum Season
    {
        Spring,
        Summer,
        Fall, 
        Winter
    }

    // 当前季节
    public Season currentSeason = Season.Spring;
    private int daysPerSeason = 30;//每季天数
    private int daysInCurrentSeason = 1;//当前季节天数

    //日期枚举类型
    public enum DayOfWeek
    {
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday,
        Saturday,
        Sunday
    }
    public DayOfWeek currentDayOfWeek = DayOfWeek.Monday;

    public int dayInGame = 1;//游戏中的天数
    public int yearInGame = 0;//游戏中的年数
    public TextMeshProUGUI dayUIText;

    private void Awake()
    {
        Instance = this;
    }

    private void Start()
    {
        UpdateUI();
    }

    // 触发过渡到下一天的方法
    public void TriggerNextDay()
    {
        // 增加游戏中的天数和当前季节的天数
        dayInGame += 1;
        daysInCurrentSeason += 1;

        currentDayOfWeek = (DayOfWeek)(((int)currentDayOfWeek + 1) % 7);

        // 检查是否当前季节天数已达到季节总天数
        if (daysInCurrentSeason > daysPerSeason)
        {
            // 切换到下一个季节,并重置季节天数计数
            daysInCurrentSeason = 1;
            currentSeason = GetNextSeason();
        }

        // 更新UI显示,触发当天过去事件
        UpdateUI();
        OnDayPass.Invoke();
    }

    // 获取下一个季节的方法
    private Season GetNextSeason()
    {
        // 计算当前季节索引和下一个季节索引
        int currentSeasonIndex = (int)currentSeason; // 获取当前季节索引
        int nextSeasonIndex = (currentSeasonIndex + 1) % 4; // 计算下一个季节索引

        // 如果下一个季节索引为0(春季),增加游戏年份
        if (nextSeasonIndex == 0)
        {
            yearInGame += 1;
        }

        // 返回下一个季节
        return (Season)nextSeasonIndex;
    }

    // 更新UI显示的方法
    private void UpdateUI()
    {
        string currentDayOfWeekChinese = getCurrentDayOfWeekChinese(currentDayOfWeek);
        string currentSeasonChinese = getCurrentSeasonChinese(currentSeason);
        dayUIText.text = $"{currentDayOfWeekChinese}{daysInCurrentSeason} 天,{currentSeasonChinese}";
    }

    //获取中文日期
    private string getCurrentDayOfWeekChinese(DayOfWeek currentDayOfWeek)
    {
        string currentDayOfWeekChinese = "";
        switch (currentDayOfWeek)
        {
            case DayOfWeek.Monday:
                currentDayOfWeekChinese = "星期一";
                break;
            case DayOfWeek.Tuesday:
                currentDayOfWeekChinese = "星期二";
                break;
            case DayOfWeek.Wednesday:
                currentDayOfWeekChinese = "星期三";
                break;
            case DayOfWeek.Thursday:
                currentDayOfWeekChinese = "星期四";
                break;
            case DayOfWeek.Friday:
                currentDayOfWeekChinese = "星期五";
                break;
            case DayOfWeek.Saturday:
                currentDayOfWeekChinese = "星期六";
                break;
            case DayOfWeek.Sunday:
                currentDayOfWeekChinese = "星期日";
                break;
            default:
                break;
        }
        return currentDayOfWeekChinese;
    }

    //获取中文季节
    private string getCurrentSeasonChinese(Season currentSeason)
    {
        string currentSeasonChinese = "";
        switch (currentSeason)
        {
            case Season.Spring:
                currentSeasonChinese = "春";
                break;
            case Season.Summer:
                currentSeasonChinese = "夏";
                break;
            case Season.Fall:
                currentSeasonChinese = "秋";
                break;
            case Season.Winter:
                currentSeasonChinese = "冬";
                break;
            default:
                break;
        }
        return currentSeasonChinese;
    }
}

配置
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d
效果
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

时间昼夜交替

素材

https://assetstore.unity.com/packages/2d/textures-materials/sky/fantasy-skybox-free-18353
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

如果没有天空盒,需要自己配置

【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

新增SkyboxBlendingShader.shader,控制天空盒平滑过渡交替变化

Shader "Custom/SkyboxTransition"
{
    Properties
    {
        _TransitionFactor("Transition Factor", Range(0, 1)) = 0.0
        _AtmosphereTex("Atmosphere CubeMap", Cube) = "" {}
        _SpaceTex("Space CubeMap", Cube) = "" {}
    }

    SubShader
    {
        Tags { "Queue"="Background" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float3 pos : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            float _TransitionFactor;
            samplerCUBE _AtmosphereTex;
            samplerCUBE _SpaceTex;

            v2f vert(appdata_t v)
            {
                v2f o;
                o.pos = v.vertex.xyz;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                // Use the transition factor to blend between the two skybox cube maps
                half4 atmosphereColor = texCUBE(_AtmosphereTex, i.pos);
                half4 spaceColor = texCUBE(_SpaceTex, i.pos);
                half4 finalColor = lerp(atmosphereColor, spaceColor, _TransitionFactor);

                return finalColor;
            }
            ENDCG
        }
    }
    FallBack "Skybox/Cubemap"
}

配置不同时间过渡材质
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d
新增DayNightSystem,负责管理游戏的昼夜系统

public class DayNightSystem : MonoBehaviour
{
    // 控制方向光的引用
    public Light directionalLight;

    // 一整天的持续时间(以秒为单位)
    public float dayDurationInSeconds = 24.0f; // 调整一整天的持续时间(以秒为单位)

    // 当前的小时
    public int currentHour;
    // 当前的分钟
    public int currentMinute;

    // 当前时间在一天中所占比例(范围在0到1之间)
    float currentTimeOfDay = 0.35f;

    // 存储不同时间段对应的天空盒
    public List<SkyboxTimeMapping> timeMappings;

    // 用于插值的值(范围在0到1之间)
    float blendedValue = 0.0f;

    // 是否锁定下一个白天触发
    bool lockNextDayTrigger = false;

    // 用于显示时间的UI元素
    public TextMeshProUGUI timeUI;

    // 在每帧更新
    void Update()
    {
        // 根据游戏时间计算当前的时间
        currentTimeOfDay += Time.deltaTime / dayDurationInSeconds;
        currentTimeOfDay = currentTimeOfDay % 1; // 确保值在0到1之间

        // 计算当前的小时
        currentHour = Mathf.FloorToInt(currentTimeOfDay * 24);
        // 计算当前的分钟数
        currentMinute = Mathf.FloorToInt(currentTimeOfDay * 1440) % 60; // 一天有 24 小时 * 60 分钟 = 1440 分钟
        //更新时间UI
        timeUI.text = $"{currentHour:D2}:{currentMinute:D2}";

        // 更新方向光的旋转
        directionalLight.transform.rotation = Quaternion.Euler(new Vector3((currentTimeOfDay * 360) - 90, 170, 0));

        // 根据时间更新天空盒材质
        UpdateSkybox();
    }

    // 更新天空盒材质的方法
    private void UpdateSkybox()
    {
        // 寻找当前小时对应的天空盒材质
        Material currentSkybox = null;
        foreach (SkyboxTimeMapping mapping in timeMappings)
        {
            if (currentHour == mapping.hour)
            {
                currentSkybox = mapping.skyboxMaterial;
                if (currentSkybox.shader != null)
                {
                    if (currentSkybox.shader.name == "Custom/SkyboxTransition")
                    {
                        blendedValue += Time.deltaTime;
                        blendedValue = Mathf.Clamp01(blendedValue);
                        currentSkybox.SetFloat("_TransitionFactor", blendedValue);
                    }
                    else
                    {
                        blendedValue = 0;
                    }
                }
                break;
            }
        }
        if (currentHour == 0 && lockNextDayTrigger == false)
        {
            TimeManager.Instance.TriggerNextDay();
            lockNextDayTrigger = true;
        }
        if (currentHour != 0)
        {
            lockNextDayTrigger = false;
        }

        // 如果找到了对应的天空盒材质,则更新RenderSettings的skybox
        if (currentSkybox != null)
        {
            RenderSettings.skybox = currentSkybox;
        }
    }
}

// 存储时间和对应天空盒材质的类
[System.Serializable]
public class SkyboxTimeMapping
{
    public string phaseName;
    public int hour; // 小时
    public Material skyboxMaterial; // 对应的天空盒材质
}

配置
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

效果
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

下雨

下雨粒子效果

这里只做个简单的,想要更复杂的下雨效果,可以看我之前的文章:【实现100个unity特效之7】unity 3d实现各种粒子效果

【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d
默认禁用雨
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

控制雨一直跟随玩家,但是旋转不跟随

//跟随玩家
public class FollowPlayer : MonoBehaviour
{
    public Transform player;
    public Vector3 offset;
    private void LateUpdate()
    {
        if (player != null)
        {
            Vector3 targetPosition = player.position + offset;
            transform.position = targetPosition;
        }
    }
}

配置
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

控制不同天气

新增WeatherSystem

public class WeatherSystem : MonoBehaviour
{
    [Range(0f, 1f)]
    public float chanceToRainSpring = 0.3f; // 春季下雨概率(30%)
    [Range(0f, 1f)]
    public float chanceToRainSummer = 0.7f; // 夏季下雨概率(70%)
    [Range(0f, 1f)]
    public float chanceToRainFall = 0.4f; // 秋季下雨概率(40%)
    [Range(0f, 1f)]
    public float chanceToRainWinter = 0f; // 冬季下雨概率(0%)

    public GameObject rainEffect; // 下雨特效
    public Material rainSkyBox; // 下雨天气的天空盒材质
    public bool isSpecialWeather; // 是否是特殊天气
    public AudioSource rainChannel; // 下雨音效的音频源
    public AudioClip rainSound; // 下雨音效

    public enum WeatherCondition
    {
        Sunny, // 晴天
        Rainy, // 下雨
        Snowy // 下雪(未在代码中实现)
    }

    private WeatherCondition currentWeather = WeatherCondition.Sunny; // 当前天气默认为晴天

    private void Start()
    {
        // 监听一天的流逝事件,用于生成随机天气
        TimeManager.Instance.OnDayPass.AddListener(GenerateRandomWeather);
    }

    private void GenerateRandomWeather()
    {
        TimeManager.Season currentSeason = TimeManager.Instance.currentSeason;
        float chanceToRain = 0f;

        // 根据当前季节设定下雨概率
        switch (currentSeason)
        {
            case TimeManager.Season.Spring:
                chanceToRain = chanceToRainSpring;
                break;
            case TimeManager.Season.Summer:
                chanceToRain = chanceToRainSummer;
                break;
            case TimeManager.Season.Fall:
                chanceToRain = chanceToRainFall;
                break;
            case TimeManager.Season.Winter:
                chanceToRain = chanceToRainWinter;
                break;
        }

        // 生成一个随机数,用于判断是否下雨
        if (Random.value < chanceToRain)
        {
            currentWeather = WeatherCondition.Rainy; // 设置为下雨天气
            isSpecialWeather = true; // 标记为特殊天气
            Invoke("StartRain", 1f); // 延迟1秒开始下雨效果
        }
        else
        {
            currentWeather = WeatherCondition.Sunny; // 设置为晴天
            isSpecialWeather = false; // 标记为非特殊天气
            StopRain(); // 停止下雨效果
        }
    }

    private void StartRain()
    {
        if (rainChannel.isPlaying == false)
        {
            rainChannel.clip = rainSound;
            rainChannel.loop = true;
            rainChannel.Play();
        }
        RenderSettings.skybox = rainSkyBox; // 切换天空盒为下雨天气材质
        rainEffect.SetActive(true); // 激活下雨特效
    }

    private void StopRain()
    {
        if (rainChannel.isPlaying)
        {
            rainChannel.Stop(); // 停止下雨音效
        }
        rainEffect.SetActive(false); // 关闭下雨特效
    }
}

修改DayNightSystem

public WeatherSystem weatherSystem;

void Update()
{
    // 。。。

    if (currentHour == 0 && lockNextDayTrigger == false)
    {
        TimeManager.Instance.TriggerNextDay();
        lockNextDayTrigger = true;
    }
    if (currentHour != 0)
    {
        lockNextDayTrigger = false;
    }

    // 根据时间更新天空盒材质
    if(weatherSystem.isSpecialWeather == false) UpdateSkybox();
}

// 更新天空盒材质的方法
private void UpdateSkybox()
{
    // 寻找当前小时对应的天空盒材质
    Material currentSkybox = null;
    foreach (SkyboxTimeMapping mapping in timeMappings)
    {
        if (currentHour == mapping.hour)
        {
            currentSkybox = mapping.skyboxMaterial;
            if (currentSkybox.shader != null)
            {
                if (currentSkybox.shader.name == "Custom/SkyboxTransition")
                {
                    blendedValue += Time.deltaTime;
                    blendedValue = Mathf.Clamp01(blendedValue);
                    currentSkybox.SetFloat("_TransitionFactor", blendedValue);
                }
                else
                {
                    blendedValue = 0;
                }
            }
            break;
        }
    }
    // 如果找到了对应的天空盒材质,则更新RenderSettings的skybox
    if (currentSkybox != null)
    {
        RenderSettings.skybox = currentSkybox;
    }
}

配置,雨声我这里就不做配置了
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

效果
【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d

源码

整理好了我会放上来

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

【unity实战】时间控制 昼夜交替 四季变化 天气变化效果,# unity实战,unity,游戏引擎,游戏,3d文章来源地址https://www.toymoban.com/news/detail-842745.html

到了这里,关于【unity实战】时间控制 昼夜交替 四季变化 天气变化效果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity中C#使用协程控制Shader材质变化

    在上一篇文章实现了C#脚本简单修改Shader材质的效果后,我们使用按钮点击结合协程来实现一下游戏中角色常见的效果:受击、中毒、消融效果 我们继续使用上一篇的 Shader 和 C# 脚本来继续测试 Unity中C#如何访问并修改Shader材质 Unity中的协程可以理解为 C# 中多线程的作用,在

    2024年02月04日
    浏览(48)
  • Unity数字可视化学校_昼夜(二)

    1、时间设置:    2、新建夜晚  3、新建侧置球(BOX),测试灯光强度  降低亮度  色调:冷色调  4、自发光  新建shader 灯光控制   道路线:  建筑:  夜晚加灯光:  玻璃:   加大灯光数量:  边缘灯光改为动态:  树:      添加粒子效果:  夜晚控制条:

    2024年02月14日
    浏览(36)
  • 【unity实战】一个通用的FPS枪支不同武器射击控制脚本

    实现FPS枪支不同武器效果,比如手枪,喷子,狙击枪,机枪,其实我最开始的想法是先做一个基类脚本,写一些公共属性和方法,然后再起不同的武器脚本这个基础基类,实现不同的武器效果。 这样的实现思路其实是没什么问题的,直到我看到这个视频:https://www.youtube.com

    2024年02月04日
    浏览(41)
  • ESP8266使用AT指令获取时间和心知天气

    一.硬件:ESP8266,USB TO TTL模块,软件:串口调试助手 二.在心知官网注册账号:心知天气 - 高精度气象数据 - 天气数据API接口 - 行业气象解决方案 三.连接esp8266和usb转ttl,打开串口调试助手 四.发送AT指令 1.复位模块 发送 AT+RST 返回 ready 2.测试AT指令 发送 AT 返回 OK 3.配置STA模式

    2024年02月04日
    浏览(54)
  • 汽车分析,随时间变化的燃油效率

    在当今快速发展的科技时代,汽车不仅是交通工具,更是科技和工程的结晶。随着社会对可持续性和环境友好的关注不断增加,燃油效率成为汽车设计和制造中的一个关键议题。一辆车的燃油效率不仅关系到驾驶者的经济负担,还直接影响到环境的可持续性。本文将深入分析

    2024年02月15日
    浏览(33)
  • 挑战杯 基于LSTM的天气预测 - 时间序列预测

    🔥 优质竞赛项目系列,今天要分享的是 机器学习大数据分析项目 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate ​ df = pd.read_csv(‘/home/kesci/input/jena1246/jena_climate_2009_2016.csv’) df.head() 如上所示,每1

    2024年02月21日
    浏览(47)
  • 【关于时间序列的ML】项目 5 :用机器学习预测天气

      🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】  深度学习【DL】 ​​  🖍foreword

    2023年04月21日
    浏览(37)
  • 计算机竞赛 基于LSTM的天气预测 - 时间序列预测

    🔥 优质竞赛项目系列,今天要分享的是 机器学习大数据分析项目 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate ​ df = pd.read_csv(‘/home/kesci/input/jena1246/jena_climate_2009_2016.csv’) df.head() 如上所示,每1

    2024年02月11日
    浏览(47)
  • 数据可视化:随时间变化的效果图

    获取北京、上海、江苏、广东四省的2008—2012年的GDP数据 在Jupyter Notebook上实现代码如下:

    2023年04月12日
    浏览(45)
  • QT 底部状态栏显示当前日期时间(每秒变化)

    效果如红框显示 首先需要引入三个头文件 其次在头文件定义两个私有变量 最后获取当前时间,设置显示模式,开启定时器 d:天,不补充0占位,1~31 dd:天,补充0占位,01~31 M:月,不补充0占位,1~12 MM:月,补充0占位,01~12 yy:年,两位显示,00~99 yyyy:年,四位显示,000

    2024年02月04日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包