【译】有趣的新mecanim功能

发表于2016-03-15
评论0 3.1k浏览

  原文地址:http://blogs.unity3d.com/2015/02/11/having-fun-with-the-new-mecanim-features/

  原文作者未做版权声明,视为共享知识产权进入公共领域,自动获得授权


  大家好!几个月前我写了一个一片关于我们在Unity5.0加入的新功能-Mecanim的文章。今天我想给你展示下利用这个新特性可以开发一些很酷又很简单的东西。


随机节点

  使用StateMachineBehaviours 创建随机的选择器节点并将它与状态机入口节点相连。



  然后你要给每一个转移条件分配一个整数型条件



  然后在状态机的Idle状态添加一个StateMachineBehaviour组件,然后像这样实现

OnStateMachineEnter接口:


override public void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
{
 
animator.SetInt(“IdleIndex”, Random.Range(0, 4));
 
}


  现在你每次进入Idle状态,一个随机状态都会被播放。


程序状态

  在Unity5.0我们也对人体动力学部分进行了一些提升,添加了我们称为IKHints的东西。这意味着你现在可以控制人体动力学的束缚了!使用StateMachineBehaviourOnStateIK回调,你可以把IK设置成你需要的特定状态。你设置可以充分发挥程序状态的威力。现在这段代码将让你的角色跳舞!

{
 
// Do a sine based on the State normalized time
 
float normalizedTime = (1.0f + Mathf.Sin(Mathf.Repeat(stateInfo.normalizedTime, 1.0f) * Mathf.PI * 4)) * 0.5f;
 
// lower the body
 
animator.bodyPosition = animator.bodyPosition + new Vector3(0, -0.3f, 0);
 
// make hands move left and right based on sine
 
Vector3 leftHandPosition = animator.bodyPosition + new Vector3(-0.1f + normalizedTime * -0.2f, 0, 0.2f);
 
Vector3 rightHandPosition = animator.bodyPosition + new Vector3(0.1f + normalizedTime * 0.2f, 0, 0.2f);
 
// put elbow up
 
Vector3 leftElbowPosition = animator.bodyPosition + new Vector3(-5, 2, 0);
 
Vector3 rightElbowPosition = animator.bodyPosition + new Vector3(5, 2, 0);
 
animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandPosition);
 
animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandPosition);
 
// align knees to the hand
 
animator.SetIKHintPosition(AvatarIKHint.LeftKnee, leftHandPosition);
 
animator.SetIKHintPosition(AvatarIKHint.RightKnee, rightHandPosition);
 
animator.SetIKHintPosition(AvatarIKHint.LeftElbow, leftElbowPosition);
 
animator.SetIKHintPosition(AvatarIKHint.RightElbow, rightElbowPosition);
 
// activate everything. Could be done on start
 
animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1.0f);
 
animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1.0f);
 
animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1.0f);
 
animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1.0f);
 
animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1.0f);
 
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1.0f);
 
animator.SetIKHintPositionWeight(AvatarIKHint.LeftKnee, 1.0f);
 
animator.SetIKHintPositionWeight(AvatarIKHint.RightKnee, 1.0f);
 
animator.SetIKHintPositionWeight(AvatarIKHint.RightElbow, 1.0f);
 
animator.SetIKHintPositionWeight(AvatarIKHint.LeftElbow, 1.0f);
 
}


创建属于你的工具

  因为我们公开了API,你可以创建各种各样的工具来创建和编辑MEcanim资产。玩2D的时候,我觉得使用Blendtrees来做状态导航是有帮助的。因为它使用精灵动画,我经常需要对不同的角色重做同样的事情一遍又一遍。我用API创建了一个简单的EditorWindow



  所以我现在只需拖我的精灵动画到目标物体上。我就像这样创建它们:




  创建控制器的代码也非常简单:

// Creates the controller
UnityEditor.Animations.AnimatorController controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath("Assets/" + target.name + ".controller");
 
// Adds 2 parameters
 
controller.AddParameter("VelX", UnityEngine.AnimatorControllerParameterType.Float);
 
controller.AddParameter("VelY", UnityEngine.AnimatorControllerParameterType.Float);
 
// Blend Tree creation
 
UnityEditor.Animations.BlendTree blendTree;
 
controller.CreateBlendTreeInController("Move", out blendTree);
 
// BlendTree setup
 
blendTree.blendType = UnityEditor.Animations.BlendTreeType.SimpleDirectional2D;
 
blendTree.blendParameter = "VelX";
 
blendTree.blendParameterY = "VelY";
 
for (int i = 0; i < animCount; ++i)
 
{
 
blendTree.AddChild(clips[i], DirectionToVector(directionValues[i]));
 
}


无处不在的状态机

  关于状态机一个很好的事情是你可以使用状态机而不需动画。所以你游戏中任何需要某种状态机相关的逻辑的时候,你都可以通过我们的可视化编辑器得到实时反馈。

  比如,一个音乐状态机:


  一个菜单状态机



很快到你表现的机会了!

  我希望这些新特性能让你感到兴奋,我们迫不及待想看到你们能用这些做出些让人激动的东西来!

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引