簡體   English   中英

試圖在RenderSettings.ambientskycolor之間束縛的Unity無法正常工作?

[英]Unity trying to lerp between RenderSettings.ambientskycolor not working?

好的,我試圖通過3種狀態來控制,每種狀態具有不同的環境光顏色。 其中一個州需要將另一種材料的Alpha約束。

我已經進行了相應的設置,但是當我觸發過渡(使用空間)時,我沒有得到平滑的束縛,而是快速閃爍,然后最終變成了最終的顏色。

編輯的代碼(仍然不完整):

  public Color[] skyColors = new Color[3];

    // added this just to see the result also in the inspector
    public Color currentAmbientcolor;

    public enum WeatherType
    {
        ClearSky,
        Clouds,
        RainStorm
    }
    public WeatherType currentWeather;

    // how long should lerping take
    // I find that easier to configure than using
    // speed - if you don't like it you can use timePassed += Tie.deltaTime * speed again
    public float LerpDuration = 1.0f;

    public Material rainMat;

    public bool isLerpingWeather;
    public bool isLerpingRain;

    // You can store those already in the beginning
    // makes it a bit better performance
    private Color rainFaidedOut;
    private Color rainFaidedIn;

    private void Awake()
    {
        rainFaidedOut = new Color(rainMat.color.r, rainMat.color.g, rainMat.color.b, 0);
        rainFaidedIn = new Color(rainMat.color.r, rainMat.color.g, rainMat.color.b, 1);

        StartCoroutine(GetWeather());
    }

    void SetWeather(string weatherval)
    {
        print("VAL: " + weatherval);
        if (weatherval.ToLower().Contains("cloud"))
        {
            currentWeather = WeatherType.Clouds;
        }
        else if (weatherval.ToLower().Contains("rain") || weatherval.ToLower().Contains("storm") || weatherval.ToLower().Contains("mist"))
        {
            currentWeather = WeatherType.RainStorm;
        }
        else
        {
            currentWeather = WeatherType.ClearSky;
        }

        //weather = WeatherType.ClearSky;
        UpdateWeather();

    }
    void UpdateWeather()
    {
        //check for change

        if (!isLerpingWeather)
        {
            if (currentWeather != WeatherType.RainStorm) rainMat.color = rainFaidedOut;

            switch (currentWeather)
            {
                case WeatherType.RainStorm:

                    RenderSettings.ambientSkyColor = skyColors[2];
                    break;

                case WeatherType.ClearSky:

                    RenderSettings.ambientSkyColor = skyColors[0];
                    break;

                case WeatherType.Clouds:

                    RenderSettings.ambientSkyColor = skyColors[1];
                    break;

                default:
                    break;
            }
        }

    }

    IEnumerator GetWeather()
    {


        //LA = [34.05, -118.24]
        //https://openweathermap.org/weather-conditions
        string url;

        WWW www = new WWW(url);
        yield return www;
        if (www.error == null)
        {

            var N = JSON.Parse(www.text);

            string weatherid = N["weather"][0]["description"];

            print(weatherid);
            SetWeather(weatherid);
        }
        else
        {
            Debug.Log("ERROR: " + www.error);

        }

    }

    private IEnumerator CycleWeather()
    {
        if (isLerpingWeather) yield break;

        isLerpingWeather = true;

        // get target color
        var currentIndex = (int)currentWeather;
        var newIndex = (currentIndex + 1) % skyColors.Length;
        var targetColor = skyColors[newIndex];
        currentWeather = (WeatherType)newIndex;

        // Here I just guessed you want that the rainMat is already
        // set to invisible when the weather has changed
        // except for RainStorm
        if (currentWeather != WeatherType.RainStorm) rainMat.color = rainFaidedOut;

        // get current color
        var currentColor = RenderSettings.ambientSkyColor;

        var timePassed = 0f;
        do
        {
            RenderSettings.ambientSkyColor = Color.Lerp(currentColor, targetColor, timePassed / LerpDuration);

            // added this just to see it in the inspector
            currentAmbientcolor = RenderSettings.ambientSkyColor;

            timePassed += Time.deltaTime;

            yield return null;
        } while (timePassed < LerpDuration);

        // just to be sure there is no over/under shooting set the target value in the end
        RenderSettings.ambientSkyColor = targetColor;

        // added this just to see it in the inspector
        currentAmbientcolor = RenderSettings.ambientSkyColor;

        isLerpingWeather = false;

        // after the currentWeather has changed start the LerpingRain routine
        // for the two cases where you want it
        // since you already have set the RenderSettings.ambientSkyColor = targetColor;
        // there is reason to do so every frame again
        if (currentWeather != WeatherType.RainStorm) StartCoroutine(LerpingRain());
    }

    private IEnumerator LerpingRain()
    {
        // skip if already lerping rain to avoid parallel routines
        if (isLerpingRain) yield break;
        // also skip if currently lerping wheather to avoid parallel routines
        if (isLerpingWeather) yield break;


        // set flag to be sure no other routine will be running
        isLerpingRain = true;

        var timePassed = 0f;
        do
        {
            rainMat.color = Color.Lerp(rainFaidedOut, rainFaidedIn, timePassed / LerpDuration);

            timePassed += Time.deltaTime;

            yield return null;
        } while (timePassed < LerpDuration);

        rainMat.color = rainFaidedIn;

        isLerpingRain = false;
    }

    // Now only used to get the input
    private void Update()
    {

        currentAmbientcolor = RenderSettings.ambientSkyColor;
        //UpdateWeather();
        // You want GetKeyDown here to execute this only once instead of every frame!
        if (Input.GetKey("space") && !isLerpingWeather)
        {
            print("changing weather");

            // Interrupt current routines
            StopAllCoroutines();
            StartCoroutine(CycleWeather());
        }
    }

我缺少什么嗎?

我建議改用協程 這將比在Update進行所有操作更容易控制:

我不得不稍微發明一下您使用的數據類型和值,但我認為它應該與您所使用的接近:

public class LerpExample : MonoBehaviour
{
    public Color[] skyColors = new Color[3];

    // added this just to see the result also in the inspector
    public Color currentAmbientcolor;

    public enum WeatherType
    {
        ClearSky,
        Clouds,
        RainStorm
    }
    public WeatherType currentWeather;

    // how long should lerping take
    // I find that easier to configure than using
    // speed - if you don't like it you can use timePassed += Tie.deltaTime * speed again
    public float LerpDuration = 1.0f;

    public Material rainMat;

    public bool isLerpingWeather;
    public bool isLerpingRain;

    // You can store those already in the beginning
    // makes it a bit better performance
    private Color rainFaidedOut;
    private Color rainFaidedIn;

    private void Awake()
    {
        rainFaidedOut = new Color(rainMat.color.r, rainMat.color.g, rainMat.color.b, 0);
        rainFaidedIn = new Color(rainMat.color.r, rainMat.color.g, rainMat.color.b, 1);
    }

    private IEnumerator CycleWeather()
    {
        if (isLerpingWeather) yield break;

        isLerpingWeather = true;

        // get target color
        var currentIndex = (int)currentWeather;
        var newIndex = (currentIndex + 1) % skyColors.Length;
        var targetColor = skyColors[newIndex];
        currentWeather = (WeatherType)newIndex;

        // Here I just guessed you want that the rainMat is already
        // set to invisible when the weather has changed
        // except for RainStorm
        if (currentWeather != WeatherType.RainStorm) rainMat.color = rainFaidedOut;

        // get current color
        var currentColor = RenderSettings.ambientSkyColor;

        var timePassed = 0f;
        do
        {
            RenderSettings.ambientSkyColor = Color.Lerp(currentColor, targetColor, timePassed / LerpDuration);

            // added this just to see it in the inspector
            currentAmbientcolor = RenderSettings.ambientSkyColor;

            timePassed += Time.deltaTime;

            yield return null;
        } while (timePassed < LerpDuration);

        // just to be sure there is no over/under shooting set the target value in the end
        RenderSettings.ambientSkyColor = targetColor;

        // added this just to see it in the inspector
        currentAmbientcolor = RenderSettings.ambientSkyColor;

        isLerpingWeather = false;

        // after the currentWeather has changed start the LerpingRain routine
        // for the two cases where you want it
        // since you already have set the RenderSettings.ambientSkyColor = targetColor;
        // there is reason to do so every frame again
        if (currentWeather != WeatherType.RainStorm) StartCoroutine(LerpingRain());
    }

    private IEnumerator LerpingRain()
    {
        // skip if already lerping rain to avoid parallel routines
        if (isLerpingRain) yield break;
        // also skip if currently lerping wheather to avoid parallel routines
        if (isLerpingWeather) yield break;


        // set flag to be sure no other routine will be running
        isLerpingRain = true;

        var timePassed = 0f;
        do
        {
            rainMat.color = Color.Lerp(rainFaidedOut, rainFaidedIn, timePassed / LerpDuration);

            timePassed += Time.deltaTime;

            yield return null;
        } while (timePassed < LerpDuration);

        rainMat.color = rainFaidedIn;

        isLerpingRain = false;
    }

    // Now only used to get the input
    private void Update()
    {
        // You want GetKeyDown here to execute this only once instead of every frame!
        if (Input.GetKey("space") && !isLerpingWeather)
        {
            print("changing weather");

            // Interrupt current routines
            StopAllCoroutines();
            StartCoroutine(CycleWeather());
        }
    }
}

立方體用於模擬雨水材質的褪色。 球體具有正常的白色材質,用於可視化環境顏色的褪色。

在此處輸入圖片說明

我不確定100%是否確實像您想要實現的那樣,但是我的目標是向您展示如何使用協程而不是Update方法中的所有那些標志和檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM