天气系统开发

using System.Collections;
using System.Collections.Generic;
using ProceduralWorlds.HDRPTOD;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;
using UnityEngine.VFX;
public enum WeatherNum
{
    Sunny,
    Cloudy,
    Foggy,
    Rainy,
    Snowy,
    Sandstorm,
    Hail,
    Lightning
}
public enum Intensity
{
    Light,
    Moderate,
    Heavy
}
public class WeatherController : MonoBehaviour
{
    private Dropdown weatherNumDropdown;
    private Dropdown intensityDropdown;

    private WeatherNum currentWeatherNum;
    private WeatherNum switchWeatherNum;
    private Intensity intensity;

    private float shapefactor;

    private VisualEffect vfx;
    private string path;
    private GameObject obj;

    private Volume rainDrop;

    private void Start()
    {
        weatherNumDropdown = GameObject.Find("WeatherNumDropdown").GetComponent<Dropdown>();
        intensityDropdown= GameObject.Find("IntensityDropdown").GetComponent<Dropdown>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.H))
        {
            rainDrop.enabled = true;
        }
    }
    /// <summary>
    /// 平滑过渡实现更新云覆盖面积参数
    /// </summary>
    /// <param name="start">起始值</param>
    /// <param name="end">目标值</param>
    /// <param name="duration">时间</param>
    /// <returns></returns>
    IEnumerator SmoothUpdateCloudShapeFactor(float start, float end, float duration)
    {
        float time = 0;
        while (time < duration)
        {
            float t = time / duration;
            shapefactor = Mathf.Lerp(start, end, t);
            Debug.Log(shapefactor);
            GetVolumetricClouds().shapeFactor.value = shapefactor;
            time += Time.deltaTime;
            yield return null;
        }
        shapefactor = end;
    }
 
    /// <summary>
    /// 设置天气  按钮调用
    /// </summary>
    public void StartWeather()
    { 
        if (currentWeatherNum == WeatherNum.Rainy || currentWeatherNum == WeatherNum.Snowy || currentWeatherNum == WeatherNum.Sandstorm)
        {
            //停止天气  -> 播放天气 ->  设置强度(可选)
            if (currentWeatherNum == switchWeatherNum)
                SetIntensity(intensity);
            else
                StartCoroutine(IESwitchWeather());
        }
        else
        {
            //播放天气  ->  设置强度(可选)
            if (currentWeatherNum==switchWeatherNum)
            {
                return;
            }
            else
            {
                StartCoroutine(IESetWI());
            }
        } 
    }

    /// <summary>
    /// 停止播放天气
    /// </summary>
    public void StopWeather()
    {
        HDRPTimeOfDayAPI.StopWeather();
    }

    /// <summary>
    /// 当前播放雨雪沙天气时,则等待20s
    /// <returns></returns>
    IEnumerator IESwitchWeather()
    { 
        StopWeather();
        Debug.Log("等20s");
        yield return new WaitForSeconds(20);
        Debug.Log("等待完成");

        StartCoroutine(IESetWI());
    }

    IEnumerator IESetWI()
    {
        SetWeatherType(switchWeatherNum);
        currentWeatherNum = switchWeatherNum;
        if (currentWeatherNum != WeatherNum.Foggy)
            RestoreFoggy();
        if (currentWeatherNum == WeatherNum.Rainy || currentWeatherNum == WeatherNum.Snowy || currentWeatherNum == WeatherNum.Sandstorm)
        {
            Debug.Log("等15s");
            yield return new WaitForSeconds(15);
            Debug.Log("等待完成");

            SetIntensity(intensity);
        }
          
    }

    /// <summary>
    /// 停止播放天气 等待20s
    /// </summary>
    /// <returns></returns>
    IEnumerator IEStopWeather()
    {
        StopWeather();
        Debug.Log("等20s");
        yield return new WaitForSeconds(20);
        Debug.Log("等待完成");
    }

    /// <summary>
    /// 设置天气 修改当前播放天气
    /// </summary>
    public void ChangeWeather()
    {
        SetWeatherType(switchWeatherNum);
        currentWeatherNum = switchWeatherNum;
    }
    /// <summary>
    /// 协程 15s后设置强度
    /// </summary>
    /// <returns></returns>
    IEnumerator IESetIntensity()
    {
        Debug.Log("等15s");
        yield return new WaitForSeconds(15);
        SetIntensity(intensity);
        Debug.Log("等待完成");
    }
    /// <summary>
    /// 晴天
    /// </summary>
    public void SetSunny()
    {
        //默认天气为晴天,阴天转换为晴天时  0.45->0.82
        //雨雪沙转换为晴天时不操作
        if (currentWeatherNum==WeatherNum.Cloudy)
        {
            StartCoroutine(SmoothUpdateCloudShapeFactor(0.45f, 0.82f, 5f));
        }
        
    }

    //------------问题--------------
    /// <summary>
    /// 阴天
    /// </summary>
    public void SetCloudy()
    {
        //晴转阴   0.82->0.45
        //-----------雨雪沙转阴  ! 000000000000  !------------
        //阴转雨有问题    云层瞬间变化
        //-------暂时------
        StartCoroutine(SmoothUpdateCloudShapeFactor(0.82f, 0.45f, 5f));
    }

    /// <summary>
    /// 雾天
    /// </summary>
    public void SetFoggy()
    {
        GetFog().meanFreePath.value = 800;
        GetFog().baseHeight.value =50000;
        GetFog().maximumHeight.value = 50000;
        GetFog().volumetricFogBudget = 3000; 
    }

    /// <summary>
    /// 恢复
    /// </summary>
    public void RestoreFoggy()
    {
        GetFog().meanFreePath.value = 6187.703f;
        GetFog().baseHeight.value = 1459.259f;
        GetFog().maximumHeight.value = 2918.519f;
    }

    /// <summary>
    /// 下雨
    /// </summary>
    public void StartRain()
    {
        HDRPTimeOfDayAPI.StartWeather(HDRPTimeOfDayAPI.GetWeatherIDByName("Rain"));  
    }

    /// <summary>
    /// 下雪
    /// </summary>
    public void StartSnow()
    {
        HDRPTimeOfDayAPI.StartWeather(HDRPTimeOfDayAPI.GetWeatherIDByName("Snow"));
    }

    /// <summary>
    /// 沙尘暴
    /// </summary>
    public void StartSandstorm()
    {
        HDRPTimeOfDayAPI.StartWeather(HDRPTimeOfDayAPI.GetWeatherIDByName("Sand"));
    }

    /// <summary>
    /// 设置天气类型
    /// </summary>
    /// <param name="wn"></param>
    public void SetWeatherType(WeatherNum wn)
    {
        switch (wn)
        {
            case WeatherNum.Sunny:
                SetSunny();
                Debug.Log("晴天");
                break;
            case WeatherNum.Cloudy:
                SetCloudy();
                Debug.Log("阴天");
                break;
            case WeatherNum.Foggy:
                SetFoggy();
                Debug.Log("雾天");
                break;
            case WeatherNum.Rainy:
                StartRain();
                Debug.Log("雨天");
                break;
            case WeatherNum.Snowy:
                StartSnow();
                Debug.Log("雪天");
                break;
            case WeatherNum.Sandstorm:
                StartSandstorm();
                Debug.Log("沙尘暴");
                break;
            case WeatherNum.Hail:

                Debug.Log("冰雹");
                break;
            case WeatherNum.Lightning:

                Debug.Log("闪电");
                break;
        }
    }

    /// <summary>
    /// 设置强度
    /// </summary>
    /// <param name="intensity"></param>
    public void SetIntensity(Intensity intensity)
    {
        GetSceneVisualEffect();
        switch (intensity)
        {
            case Intensity.Light:
                vfx.SetFloat("ParticleAmount", 1000);
                Debug.Log("轻度");
                break;
            case Intensity.Moderate:
                vfx.SetFloat("ParticleAmount", 3000);
                Debug.Log("中度");
                break;
            case Intensity.Heavy:
                vfx.SetFloat("ParticleAmount", 8000);
                Debug.Log("重度");
                break;
        }
    }

    /// <summary>
    /// 获取VFX
    /// </summary>
    public void GetSceneVisualEffect()
    {
        //物体 vfx  粒子数量
        //从场景中找Rain 如果有则修改,没有则从资源中加载
        //根据天气类型 得到(Rain)名字,资源中加载(Rain)预制体,得到VFX组件,根据强度修改粒子数量
        if (currentWeatherNum==WeatherNum.Rainy)
        {
            vfx = GameObject.Find("Rain(Clone)").GetComponent<VisualEffect>();
        }
        else if(currentWeatherNum == WeatherNum.Snowy)
        {
            vfx = GameObject.Find("SnowBlizzard(Clone)").GetComponent<VisualEffect>();
        }
        else if (currentWeatherNum == WeatherNum.Sandstorm)
        {
            vfx = GameObject.Find("SandGroundDust(Clone)").GetComponent<VisualEffect>();
        }
    }

    /// <summary>
    /// 获取体积云组件
    /// </summary>
    /// <returns></returns>
    public VolumetricClouds GetVolumetricClouds()
    {
        VolumeProfile profile = GameObject.Find("Time Of Day Components").GetComponent<Volume>().sharedProfile;
        profile.TryGet<VolumetricClouds>(out var clouds);
        return clouds;
    }

    /// <summary>
    /// 获取雾
    /// </summary>
    /// <returns></returns>
    public Fog GetFog()
    {
        VolumeProfile profile = GameObject.Find("Time Of Day Components").GetComponent<Volume>().sharedProfile;
        profile.TryGet<Fog>(out var fog);
        return fog;
    }
   
    /// <summary>
    /// 天气值变化
    /// </summary>
    public void OnWeaatherNumDropDownValueChange()
    {
        switch (weatherNumDropdown.value)
        {
            case 0:
                switchWeatherNum = WeatherNum.Sunny;
                break;
            case 1:
                switchWeatherNum = WeatherNum.Cloudy;
                break;
            case 2:
                switchWeatherNum = WeatherNum.Foggy;
                break;
            case 3:
                switchWeatherNum = WeatherNum.Rainy;
                break;
            case 4:
                switchWeatherNum = WeatherNum.Snowy;
                break;
            case 5:
                switchWeatherNum = WeatherNum.Sandstorm;
                break;
            case 6:
                switchWeatherNum = WeatherNum.Hail;
                break;
            case 7:
                switchWeatherNum = WeatherNum.Lightning;
                break;
        }
    }

    /// <summary>
    /// 强度值变化
    /// </summary>
    public void OnIntensityDropDownValueChange()
    {
        switch (intensityDropdown.value)
        {
            case 0:
                intensity = Intensity.Light;
                break;
            case 1:
                intensity = Intensity.Moderate;
                break;
            case 2:
                intensity = Intensity.Heavy;
                break;
        }
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_53163894/article/details/132619967