Unity:如何为闪烁的 TextMesh 制作动画(当玩家做某事时改变 alpha)?
Unity: How to animate a flashing TextMesh (so varying the alpha when the player does something)?
我尝试过追溯生存射击教程中的步骤(在 TextMesh 的 属性 上创建一个动画剪辑,改变 alpha,并创建一个状态机),但是动画 alpha 属性 在 textMesh.MeshRenderer._Color 对象中什么都不做,因为这个对象在运行时消失了(即使动画师 window 接受它作为一个有效的动画对象...),而我的动画 window当我重新打开它时实际上显示该对象丢失了——所以我在想这一定是某种一次性的彩色对象?
问题是这是我唯一可以在文本网格对象中编辑的 "color"。否则,状态机运行良好;并且动画似乎正在播放...只是什么都没发生...而且,就像我说的,当我在动画 window 中重新打开动画剪辑时,属性 被标记为 'missing,' 即使我没有触及相应的对象。
回到我正在尝试做的事情:我正在尝试在游戏中(而不是在 HUD 上)实现一个闪烁的标签,该标签在玩家靠近之前是不可见的,然后它开始缓慢闪烁(它是控制建议)。也许 Textmesh 对象是错误的对象;也许我的动画过程是错误的......但我认为更简单的答案可能是进入如何实现我正在尝试做的事情......而不是解决我正在犯的错误......
您可以使用动画和代码来完成此操作。我会选择代码。使用 Coroutines
、lerp
和 Time.deltaTime
,几乎任何类型的动画都可以在 Unity 中实现。当 startTextMeshAnimation()
被调用时,下面的代码将闪烁 TextMesh 并继续直到 stopTextMeshAnimation()
被调用。您可以通过调用 changeTextMeshAnimationSpeed()
并传入速度值来更改速度。这是几秒钟。 0.2 到 5f 都可以。
public TextMesh textMesh;
public float animSpeedInSec = 1f;
bool keepAnimating = false;
private IEnumerator anim()
{
Color currentColor = textMesh.color;
Color invisibleColor = textMesh.color;
invisibleColor.a = 0; //Set Alpha to 0
float oldAnimSpeedInSec = animSpeedInSec;
float counter = 0;
while (keepAnimating)
{
//Hide Slowly
while (counter < oldAnimSpeedInSec)
{
if (!keepAnimating)
{
yield break;
}
//Reset counter when Speed is changed
if (oldAnimSpeedInSec != animSpeedInSec)
{
counter = 0;
oldAnimSpeedInSec = animSpeedInSec;
}
counter += Time.deltaTime;
textMesh.color = Color.Lerp(currentColor, invisibleColor, counter / oldAnimSpeedInSec);
yield return null;
}
yield return null;
//Show Slowly
while (counter > 0)
{
if (!keepAnimating)
{
yield break;
}
//Reset counter when Speed is changed
if (oldAnimSpeedInSec != animSpeedInSec)
{
counter = 0;
oldAnimSpeedInSec = animSpeedInSec;
}
counter -= Time.deltaTime;
textMesh.color = Color.Lerp(currentColor, invisibleColor, counter / oldAnimSpeedInSec);
yield return null;
}
}
}
//Call to Start animation
void startTextMeshAnimation()
{
if (keepAnimating)
{
return;
}
keepAnimating = true;
StartCoroutine(anim());
}
//Call to Change animation Speed
void changeTextMeshAnimationSpeed(float animSpeed)
{
animSpeedInSec = animSpeed;
}
//Call to Stop animation
void stopTextMeshAnimation()
{
keepAnimating = false;
}`
我尝试过追溯生存射击教程中的步骤(在 TextMesh 的 属性 上创建一个动画剪辑,改变 alpha,并创建一个状态机),但是动画 alpha 属性 在 textMesh.MeshRenderer._Color 对象中什么都不做,因为这个对象在运行时消失了(即使动画师 window 接受它作为一个有效的动画对象...),而我的动画 window当我重新打开它时实际上显示该对象丢失了——所以我在想这一定是某种一次性的彩色对象?
问题是这是我唯一可以在文本网格对象中编辑的 "color"。否则,状态机运行良好;并且动画似乎正在播放...只是什么都没发生...而且,就像我说的,当我在动画 window 中重新打开动画剪辑时,属性 被标记为 'missing,' 即使我没有触及相应的对象。
回到我正在尝试做的事情:我正在尝试在游戏中(而不是在 HUD 上)实现一个闪烁的标签,该标签在玩家靠近之前是不可见的,然后它开始缓慢闪烁(它是控制建议)。也许 Textmesh 对象是错误的对象;也许我的动画过程是错误的......但我认为更简单的答案可能是进入如何实现我正在尝试做的事情......而不是解决我正在犯的错误......
您可以使用动画和代码来完成此操作。我会选择代码。使用 Coroutines
、lerp
和 Time.deltaTime
,几乎任何类型的动画都可以在 Unity 中实现。当 startTextMeshAnimation()
被调用时,下面的代码将闪烁 TextMesh 并继续直到 stopTextMeshAnimation()
被调用。您可以通过调用 changeTextMeshAnimationSpeed()
并传入速度值来更改速度。这是几秒钟。 0.2 到 5f 都可以。
public TextMesh textMesh;
public float animSpeedInSec = 1f;
bool keepAnimating = false;
private IEnumerator anim()
{
Color currentColor = textMesh.color;
Color invisibleColor = textMesh.color;
invisibleColor.a = 0; //Set Alpha to 0
float oldAnimSpeedInSec = animSpeedInSec;
float counter = 0;
while (keepAnimating)
{
//Hide Slowly
while (counter < oldAnimSpeedInSec)
{
if (!keepAnimating)
{
yield break;
}
//Reset counter when Speed is changed
if (oldAnimSpeedInSec != animSpeedInSec)
{
counter = 0;
oldAnimSpeedInSec = animSpeedInSec;
}
counter += Time.deltaTime;
textMesh.color = Color.Lerp(currentColor, invisibleColor, counter / oldAnimSpeedInSec);
yield return null;
}
yield return null;
//Show Slowly
while (counter > 0)
{
if (!keepAnimating)
{
yield break;
}
//Reset counter when Speed is changed
if (oldAnimSpeedInSec != animSpeedInSec)
{
counter = 0;
oldAnimSpeedInSec = animSpeedInSec;
}
counter -= Time.deltaTime;
textMesh.color = Color.Lerp(currentColor, invisibleColor, counter / oldAnimSpeedInSec);
yield return null;
}
}
}
//Call to Start animation
void startTextMeshAnimation()
{
if (keepAnimating)
{
return;
}
keepAnimating = true;
StartCoroutine(anim());
}
//Call to Change animation Speed
void changeTextMeshAnimationSpeed(float animSpeed)
{
animSpeedInSec = animSpeed;
}
//Call to Stop animation
void stopTextMeshAnimation()
{
keepAnimating = false;
}`