我偶然发现了一些我从未想象过会成为问题的东西,但......就是这样。 我正在使用unity 5.5编写visualiazion / simulation工具包。
已导入已使用的模型,并通过编辑器设置动画片段。这就是我的动画状态控制器的样子:
我想在DropdownMenu中显示AnimationStates。每当用户选择条目时,应将当前动画状态设置为所选动画状态。
e.G。用户选择自动播放:状态设置为剪辑自动播放,之后是SimpleRotate,然后是ComplexRotate,再次是自动播放(只是一个简单的循环)。
但是如果用户选择Idle,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)
}
最重要的是,如果我可以检查转换FROM和TO状态会很好。 (自动播放是唯一应该在循环的下拉列表中显示的状态)
这可以通过自定义动画控制器实现吗?或者我错过了什么?
答案 0 :(得分:4)
我在这里看到两个选项。一个相当简单的,一个更复杂,但更健壮的一个。
选项一
您使用RuntimeAnimatorController
。这将在运行时在给定的Animator中获得all the AnimationClips。您可以使用Animator.Play(StateNameOrHash)
在任何给定时间在AnimatorController中播放状态。不幸的是,对于这个选项,这只会通过其Name或NameHash(作为docs中的statet)来播放状态。因为我们只有AnimationClips
而不是Controller中的状态,所以此选项将涉及将控制器中的状态重命名为动画剪辑的确切名称。然后你可以扮演这样一个状态:
myAnimator.Play(myAnimationClip.name);
这是一个快速入门的选项,但从长远来看这不是一个好选择,因为它有两个缺点:
AnimationClip
表示。因此,您无法通过RuntimeAnimatorController
来审查这些州,因为它只会返回AnimationClips
AnimationClips
。我不知道你的情况,但最好使用描述性的名字,然后使用动画片段中的名字,以便更好地理解。选项二
此选项更复杂。我将为您提供工作流程的快速概述,然后更详细地解释这些部分或提供参考资料以帮助您入门!
第1部分: 使用编辑器脚本extract all the States from your 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);
}
请注意:使用的AnimatorController
位于UnityEditor.Animations
命名空间内。这可以是EditorScript中的公共字段,以便您轻松访问。
第2部分:您的脚本文件应该创建一个类似这样的类:
public class AnimatorControllerStates
{
public List<string> states = new List<string>
{
"Idle",
"ComplexRotate 0",
"Autoplay",
...
}
}
以与您为其创建的AnimatorController相关的方式命名该类。并使此类成为运行时脚本中的一个字段。然后你可以访问你所有的州:
myAnimatorControllerStates.states
此数组可以填充您的下拉列表。您可以保存下拉列表的索引,然后可以通过索引播放状态。
第3部分:现在,在您的脚本中播放您的状态真的很容易:
string state = myAnimatorControllerStates.states[mySelectedIndex];
myAnimatorController.Play(mySelectedIndex);
我不知道你的项目的范围,但是为了拥有一个可维护的应用程序,我希望随时选择二。