Unity - 如何在某个动画状态开启时进行 lerp?
Unity - how to lerp while a certain animation state is on?
好的,所以我有一个动画,它的速度由用户的敲击 m 控制,这意味着我不能只在设定的时间内 lerp,但必须让它取决于这是否属实:
cameraAnim.GetCurrentAnimatorStateInfo (0).IsName ("stillOpening")
在这个动画结束时(无论它花了多长时间,快或慢)我需要在我的 material 中浮动到它的最终值:
skybox.SetFloat ("_Exponent1",Mathf.Lerp(skybox.GetFloat("_Exponent1"), topSkyBoxOpen, ratio));
意味着它必须等于 "stillOpening" 末尾的 topSkyBoxOpen。我不知道如何协调时间。
我已经在 Update() 中尝试过:
void openSkyLerp()
{
float ratio = 0;
float duration = 0.5f; // this is the one that will control how long it takes
// value is in second
float multiplier = 1 / duration;
while (cameraAnim.GetCurrentAnimatorStateInfo (0).IsName ("stillOpening")) {
ratio += Time.deltaTime * multiplier;
skybox.SetFloat ("_Exponent1",Mathf.Lerp(skybox.GetFloat("_Exponent1"), topSkyBoxOpen, ratio));
}
}
但什么也没有发生 - 我读到这可能是因为它试图在 1 帧内进行所有插补。这可能吗?无论速度如何,我如何在播放动画时进行插补?
Meaning it has to be equal to topSkyBoxOpen at the end of
"stillOpening". I don't know how to coordinate the timing.
问题是您甚至没有在等待帧。所以,即使你的等式是正确的,所有这些也不能在一帧内顺利发生。您等待 yield return null;
的帧,这需要协程。
几个小时前回答了一个非常相似但不是 the-same 。
如果 stillOpening
变量是目标值,则在进入 while 循环之前获取当前 _Exponent1
值。有一个计数器变量,当计数器小于 topSkyBoxOpen
时每帧递增。然后,您可以在 SetFloat
函数中使用 Mathf.Lerp(currentVal, topSkyBoxOpen, counter / duration);
。
bool running = false;
void openSkyLerp()
{
if (running)
{
return;
}
running = true;
StartCoroutine(OpenSky(5));
}
IEnumerator OpenSky(float duration)
{
float currentVal = skybox.GetFloat("_Exponent1");
float counter = 0;
while (counter < topSkyBoxOpen)
{
//Exit if not still opening
if (!cameraAnim.GetCurrentAnimatorStateInfo(0).IsName("stillOpening"))
{
yield break;
}
counter = counter + Time.deltaTime;
float val = Mathf.Lerp(currentVal, topSkyBoxOpen, counter / duration);
skybox.SetFloat("_Exponent1", val);
yield return null; //Wait for a frame
}
running = false;
}
好的,所以我有一个动画,它的速度由用户的敲击 m 控制,这意味着我不能只在设定的时间内 lerp,但必须让它取决于这是否属实:
cameraAnim.GetCurrentAnimatorStateInfo (0).IsName ("stillOpening")
在这个动画结束时(无论它花了多长时间,快或慢)我需要在我的 material 中浮动到它的最终值:
skybox.SetFloat ("_Exponent1",Mathf.Lerp(skybox.GetFloat("_Exponent1"), topSkyBoxOpen, ratio));
意味着它必须等于 "stillOpening" 末尾的 topSkyBoxOpen。我不知道如何协调时间。
我已经在 Update() 中尝试过:
void openSkyLerp()
{
float ratio = 0;
float duration = 0.5f; // this is the one that will control how long it takes
// value is in second
float multiplier = 1 / duration;
while (cameraAnim.GetCurrentAnimatorStateInfo (0).IsName ("stillOpening")) {
ratio += Time.deltaTime * multiplier;
skybox.SetFloat ("_Exponent1",Mathf.Lerp(skybox.GetFloat("_Exponent1"), topSkyBoxOpen, ratio));
}
}
但什么也没有发生 - 我读到这可能是因为它试图在 1 帧内进行所有插补。这可能吗?无论速度如何,我如何在播放动画时进行插补?
Meaning it has to be equal to topSkyBoxOpen at the end of "stillOpening". I don't know how to coordinate the timing.
问题是您甚至没有在等待帧。所以,即使你的等式是正确的,所有这些也不能在一帧内顺利发生。您等待 yield return null;
的帧,这需要协程。
几个小时前回答了一个非常相似但不是 the-same
如果 stillOpening
变量是目标值,则在进入 while 循环之前获取当前 _Exponent1
值。有一个计数器变量,当计数器小于 topSkyBoxOpen
时每帧递增。然后,您可以在 SetFloat
函数中使用 Mathf.Lerp(currentVal, topSkyBoxOpen, counter / duration);
。
bool running = false;
void openSkyLerp()
{
if (running)
{
return;
}
running = true;
StartCoroutine(OpenSky(5));
}
IEnumerator OpenSky(float duration)
{
float currentVal = skybox.GetFloat("_Exponent1");
float counter = 0;
while (counter < topSkyBoxOpen)
{
//Exit if not still opening
if (!cameraAnim.GetCurrentAnimatorStateInfo(0).IsName("stillOpening"))
{
yield break;
}
counter = counter + Time.deltaTime;
float val = Mathf.Lerp(currentVal, topSkyBoxOpen, counter / duration);
skybox.SetFloat("_Exponent1", val);
yield return null; //Wait for a frame
}
running = false;
}