[英]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.