Unity Animator 窗口的控制
2016-08-26 21:36
447 查看
问题描述
Animator 窗口默认显示的是 Base Layer 的动画状态机,每次要编辑子状态机里的状态动画时,都得手动双击进到子状态机里,非常不便。研究编辑器代码,来达到自动显示子状态机界面,如下面所示:
实现分析
Animator 窗口的实现类,位于目录 "Unity\Editor\Data\Managed\UnityEditor.Graphs.dll",反编译 DLL,AnimatorControllerTool 类就是具体实现。这是顶部的状态机视图切换导航,它的列表保存在 AnimatorControllerTool.m_BreadCrumbs (面包屑)数组里面,点击的时候会调用 GoToBreadCrumbTarget 方法,将跳到所点击的状态机里,这个方法会将 m_BreadCrumbs 所点击的数组索引之后的值删除掉,然后调用 UpdateStateMachineSelection 方法。这个方法,会将 m_BreadCrumbs 数组的最后一个值作为显示的状态机。
所要用到的 API 接口:
当前显示的动画状态机,通过接口 UnityEditor.Graphs.AnimationStateMachine.Graph.activeStateMachine 来获得。
构建面包屑路径通过 AnimatorControllerTool.BuildBreadCrumbsFromSMHierarchy 方法来实现。
如果当前已经是要设置的动画状态机了,那就不做任何操作。如果不是的话,再来构建面包屑路径。
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public static void SetActiveStateMachine(AnimatorController animatorController, AnimatorStateMachine animatorStateMachine) { InitReflect(); AnimatorStateMachine activeStateMachine = animatorControllerToolReflect.activeStateMachine; if (animatorStateMachine != activeStateMachine && animatorStateMachine != null) { List<AnimatorStateMachine> hierarchy = new List<AnimatorStateMachine>(); AnimatorControllerUtil.MecanimUtilities_StateMachineRelativePath( AnimatorControllerUtil.AnimatorController_BaseLayerStateMachine(animatorController), animatorStateMachine, ref hierarchy); animatorControllerToolReflect.BuildBreadCrumbsFromSMHierarchy(hierarchy); } } |
MecanimUtilities_StateMachineRelativePath 方法,是获取两个状态机直接的路径,详见 UnityEditor.Animations.MecanimUtilities 类;
AnimatorController_BaseLayerStateMachine 方法,是获取控制器的最底层状态机;
视图滚动到指定的状态
每当状态机里面状态过多的时候,寻找指定的状态,总是很麻烦,要一直拖动视图。现在通过获取状态的 position 来滚动到此位置。通过打印坐标位置来得到上面的关系
信息分别如下:
状态的坐标,即 ChildAnimatorState 的 position 值;
当前视图的 scrollPosition 值;
当前视图的 graphExtents 值;
那么要控制滚动位置的话,通过 graphExtents 减去状态的 position 值来实现,代码如下:
1 2 3 4 5 6 7 8 9 10 | public static void ScrollToState(AnimatorStateMachine animatorStateMachine, AnimatorState state) { InitReflect(); Vector3 pos = AnimatorControllerUtil.AnimatorStateMachine_GetStatePosition(animatorStateMachine, state); Rect graphExtents = animatorControllerToolReflect.graphExtents; Vector2 pos2 = new Vector2(pos.x - graphExtents.x, pos.y - graphExtents.y); animatorControllerToolReflect.scrollPosition = pos2; } |
但是一般都是将状态至于中间,才能方便看到与状态有关的过渡线。视图的大小保存在 GraphGUI 的 m_GraphClientArea 变量里。那么居中的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 | public static void ScrollToState(AnimatorStateMachine animatorStateMachine, AnimatorState state) { InitReflect(); Vector3 pos = AnimatorControllerUtil.AnimatorStateMachine_GetStatePosition(animatorStateMachine, state); Rect graphExtents = animatorControllerToolReflect.graphExtents; Rect graphClientArea = animatorControllerToolReflect.graphClientArea; Vector2 pos2 = new Vector2(pos.x - graphExtents.x - graphClientArea.width / 2 + 100f, pos.y - graphExtents.y - graphClientArea.height / 2 + 25f); animatorControllerToolReflect.scrollPosition = pos2; } |
完整代码
代码路径:https://gist.github.com/akof1314/65ca8ffcf64ccdc802730ddade71a8ff
相关文章推荐
- Unity用程序给Animator控制的某一个动画(AnimationClip)加一个动画事件(AnimationEvent)
- Unity里用Animator控制3dmax里制作的动画
- unity animator动画融合时的上下半身速度分离控制
- [置顶] Unity打包exe后去除原生窗口,使用自己的窗口控制UI,修改了网上的很多bug
- Unity 编辑器下控制播放Animator
- [Unity][Animation]通过Animator来控制子物体的升起下落
- Unity-Animator深入系列---控制IK
- Unity 编辑器下控制播放Animator
- Unity5.5+easytouch5双摇杆控制角色移动及挂上Animator的方法
- unity 长按按钮控制播放animator播放速度
- Autosizer应用程序窗口控制工具
- Unity 方向控制及鼠标滚轮代码控制
- 用javascript实现控制打开网页窗口的大小 和HTML如何关闭窗口的技巧大全
- C#模拟鼠标键盘控制其他窗口
- Unity-Animator深入系列---API详解
- Unity教程之手把手教你Animator状态机如何切换状态
- Unity 3D 控制物体前后左右均匀移动脚本
- 子线程如何获取和设置 或者控制窗口实时显示数据(网上的资料经个人整理拼凑总结)
- Unity 中,FPS 第一人称行走,按A键,一直后退。WASD方向控制错误
- CSS实现子级窗口高度随低级窗口高度变化及js控制左右容器高度一致