Maz*_*yod 5 graphics animation unity-game-engine
我有一个在 Unity 中运行的非常简单的游戏,不幸的是,它没有按预期工作。
我有以下设置:

(来源:mazyod.com)
在任何状态下,如果整数参数direction等于1,则设置 animation player_move_e。对于2, 3,4其他方向也是如此。一旦direction被设定为0,与该方向相关联的空闲的动画被播放。
这里要指出的重要一点是,由于我使用的是“任何状态”块,我必须确保一旦动画状态更改为移动动画状态之一,我将重置direction为标记值,例如-1,保持动画状态在当前状态中,并且不会再次将状态更改为自身。
当播放器处于move_n状态时,我迅速将方向更改为,例如move_e(没有给它足够的时间过渡到空闲),动画状态停留在move_n:(
我如何知道转换是否发生,并且我不经常更新?起初,我正在更新direction中FixedUpdate,然后移动它Update,但它在这两种方法同样的问题。
这是我看到的逻辑:
// MY CODE
animator.SetInteger(1); // Initially, it's move_e
...
// WITHIN UNITY (making it up)
Unity.UpdateStates(); // The number is read in the engine, and transition happens
...
// MY CODE
animator.SetInteger(-1); // Stay at current animation
...
// WITHIN UNITY (making it up)
Unity.UpdateStates(); // The number is read in the engine, nothing should happen
...
// MY CODE
animator.SetInteger(0); // The logic briefly changes to idle
...
// WITHIN UNITY (making it up)
Unity.UpdateStates(); // The number is read in the engine, transition to idle
...
// MY CODE
animator.SetInteger(4); // transition to north
...
// WITHIN UNITY (making it up)
// NOTHING HAPPENS!! It doesn't catch up
...
// MY CODE
animator.SetInteger(-1); // Stay at current state, assuming it changed to move_n
...
// WITHIN UNITY (making it up)
Unity.UpdateStates(); // The number is read in the engine, stays at idle_e!
...
Run Code Online (Sandbox Code Playgroud)
这是整个代码:
void Update()
{
// update animator (Stupid transition from any state includes current state -_-")
int heading = CalculateHeading(horizontalInput, verticalInput);
if (heading != previousHeading)
{
anim.SetInteger("direction", heading);
previousHeading = heading;
}
else
{
anim.SetInteger("direction", -heading);
}
}
void MovementManagement ()
{
// If there is some axis input...
if(horizontalInput != 0f || verticalInput != 0f)
{
Vector3 position = transform.position;
position.x += horizontalInput * movementSpeed;
position.y += verticalInput * movementSpeed;
transform.position = position;
}
}
int CalculateHeading(float horizontal, float vertical)
{
if (horizontal == 0f && vertical == 0f)
{
return 0;
}
if (Mathf.Abs(horizontal) > Mathf.Abs(vertical))
{
return (horizontal > 0 ? 1 : 3);
}
else
{
return (vertical > 0 ? 4 : 2);
}
}
Run Code Online (Sandbox Code Playgroud)
我为自己构建了一个小场景并玩了一下。我可以重现您的问题,甚至找到了一个简单的解决方案。
为什么会发生这种情况
当动画器状态机仍在过渡到新状态时,似乎会出现此问题。在此期间,新的参数值将被忽略,但您的代码将在下一次update()调用中再次更改该值。direction = -1例如,状态机忽略了您的新方向,现在只能看到没有可用转换的值。
转换的默认行为是atomic,根据参考,它不能被中断。但是,将其设置为 false 没有什么区别...这可能是一个错误,您可能需要提交错误报告。
解决方案
您需要通过IsInTransition(int layer)如下检查来检查状态机当前是否处于转换中:
void Update()
{
// update animator (Stupid transition from any state includes current state -_-")
int heading = CalculateHeading(horizontalInput, verticalInput);
if (heading != previousHeading && !anim.IsInTransition(0)) // you may need to adjust the layer index
{
anim.SetInteger("direction", heading);
previousHeading = heading;
}
else
{
anim.SetInteger("direction", -heading);
}
}
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案
我不知道您对不同方向使用哪种动画,但使用一种动画并只需转动角色可能会更容易:)这样您就可以减少过渡和状态,并且可以更轻松地添加更多稍后动画。