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