我偶然发现了一些我从未想过的问题,但是...确实如此。我正在使用unity 5.5编写visualiazion / simulation工具箱。
使用的模型已经导入,并且通过编辑器设置了动画剪辑。这是我的动画状态控制器的外观:
eG用户选择了自动播放:将状态设置为剪辑自动播放,然后设置为SimpleRotate,然后设置为ComplexRotate,然后再次设置为自动播放(只是一个简单的循环)。
但是,如果用户选择“空闲”,“ ComplexRotate 0”或“ SimpleRotate 0”,则动画应播放一次,然后停留在剪辑的结尾。(就像我在动画控制器中所做的一样。
这是我想要的一个相当伪的版本:
//Retrieve all states to populate the dropdown: Liststates = myAnimationController.GetAllStates(); foreach(AnimationState state in states) Dropdown.add(state.name) //callback OnDropdownIndexChanged(int item) { string stateName = ..... //removed for simplicity myAnimationController.setState(stateName) }
最重要的是,如果我可以检查FROM和TO状态之间的转换,那就太好了。(自动播放是应该在循环的下拉菜单中显示的唯一状态)
可以通过自定义动画控制器实现此功能吗?还是我错过了什么?
我在这里看到两个选择。一个相当简单的工具,但是比较复杂,但是功能强大。
选项一
您使用RuntimeAnimatorController
。这将在运行时为您提供给定Animator中的所有AnimationClip。您可以使用随时在AnimatorController中播放State Animator.Play(StateNameOrHash)
。不幸的是,这个选项,这样只会通过其名称或NameHash(如statet发挥国家文档)。因为我们只有AnimationClips
Controller的State而没有States,所以此选项涉及将Controller中的State重命名为Animation Clip的确切名称。然后,您可以播放一个像这样的状态:
myAnimator.Play(myAnimationClip.name);
这是一个入门的快速选择,但从长远来看不是一个好的选择,因为它本质上有两个缺点:
您只能在AnimatorController中使用平面层次结构。没有SubStateMachines / Blendtree,因为它们没有以表示AnimationClip
。因此,您将无法通过检索这些国家,RuntimeAnimatorController
因为它只会返回AnimationClips
AnimatorController可能很难理解,因为状态命名为AnimationClips
。我在这里不了解您的情况,但是最好使用描述性名称,然后使用AnimationClips中的名称,以更好地理解。
选项二
这个选项比较复杂。我将为您提供工作流程的快速概述,然后更详细地解释各部分或提供参考以帮助您入门!
[Editor Script]从AnimatorController生成包含所有状态的脚本。(可能是“最难的”部分)
使用生成的脚本用状态填充您的下拉菜单
发挥你的状态:)
第1部分: 使用编辑器脚本从AnimatorController中提取所有状态。此链接应为您提供有关如何实现此目的的提示。简短(未经测试)的示例代码:
private void writeAllStates() { AnimatorControllerLayer[] allLayer = controller.layers; ListstateNames = new List (); for (int i = 0; i < allLayer.Length; i++) { ChildAnimatorState[] states = allLayer[i].stateMachine.states; for (int j = 0; j < states.Length; j++) { // you could do additional filtering here. like "would i like to add this state to my list because it has no exit transition" etc if (shouldBeInserted(states[i])) { // add state to list stateNames.Add(states[j].state.name); } } } // now generate a textfile to write all the states FileGenerator.createFileForController(controller, stateNames); }
请记住:所使用的AnimatorController
是内部UnityEditor.Animations
的命名空间。这可以是EditorScript中的公共字段,以轻松为您提供访问权限。
第2部分:您的脚本文件应创建一个类似于该类的类:
public class AnimatorControllerStates { public Liststates = new List { "Idle", "ComplexRotate 0", "Autoplay", ... } }
将该类命名为与您为其创建的AnimatorController相关的类。并将此类作为运行时脚本中的一个字段。然后,您可以像这样访问所有状态:
myAnimatorControllerStates.states
该数组可以填充您的下拉列表。您将保存下拉列表的索引,然后可以通过索引播放状态。
第3部分:现在,只需在脚本中播放状态就非常容易了:
string state = myAnimatorControllerStates.states[mySelectedIndex]; myAnimatorController.Play(mySelectedIndex);
我不知道您的项目范围,但是要拥有一个可维护的应用程序,我随时都希望选择第二种方法。