我在Unity中运行了一个非常简单的游戏,不幸的是,它没有按预期运行。
我有以下设置:
http://mazyod.com/images/Screenshot_2014-04-23_10.51.20.png
在任何状态下,如果整数参数direction
等于1
,请设置动画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!
...
以下是整个代码:
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);
}
}
答案 0 :(得分:2)
我为自己建了一个小场景,玩了一下。我可以重现你的问题,甚至找到一个简单的解决方案。
为什么会发生
当动画师状态机仍处于转换到新状态时,似乎会出现问题。在此期间,将忽略新参数值,但您的代码将在下一次update()
调用中再次更改该值。状态机忽略了您的新方向,现在只能看到没有可用转换的值,例如direction = -1
。
转换的默认行为是atomic
,这意味着根据reference它不能被中断。但是,将其设置为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);
}
}
另一种可能的解决方案
我不知道你在不同的方向使用什么样的动画,但是使用一个动画可能更容易,只需转动你的角色:)这样你就可以减少过渡和状态,并且可能更容易稍后添加更多动画。