Animator Override Controller

601 阅读6分钟

AnimatorOverrideController类继承自RuntimeAnimatorController:

public class AnimatorOverrideController : RuntimeAnimatorController
    {
        //
        // Summary:
        //     Creates an empty Animator Override Controller.
        public AnimatorOverrideController();
        //
        // Summary:
        //     Creates an Animator Override Controller that overrides controller.
        //
        // Parameters:
        //   controller:
        //     Runtime Animator Controller to override.
        public AnimatorOverrideController(RuntimeAnimatorController controller);

        public AnimationClip this[string name] { get; set; }
        public AnimationClip this[AnimationClip clip] { get; set; }

        //
        // Summary:
        //     The Runtime Animator Controller that the Animator Override Controller overrides.
        public RuntimeAnimatorController runtimeAnimatorController { get; set; }
        //
        // Summary:
        //     Returns the count of overrides.
        public int overridesCount { get; }
        //
        // Summary:
        //     Returns the list of orignal Animation Clip from the controller and their override
        //     Animation Clip.
        [Obsolete("AnimatorOverrideController.clips property is deprecated. Use AnimatorOverrideController.GetOverrides and AnimatorOverrideController.ApplyOverrides instead.")]
        public AnimationClipPair[] clips { get; set; }

        public void ApplyOverrides(IList<KeyValuePair<AnimationClip, AnimationClip>> overrides);
        public void GetOverrides(List<KeyValuePair<AnimationClip, AnimationClip>> overrides);
    }
}

AnimatorController也继承自RuntimeAnimatorController:

namespace UnityEditor.Animations
{
    //
    // Summary:
    //     The Animator Controller controls animation through layers with state machines,
    //     controlled by parameters.
    [NativeClass(null)]
    [NativeHeader("Editor/Src/Animation/AnimatorController.bindings.h")]
    [NativeHeader("Editor/Src/Animation/StateMachineBehaviourScripting.h")]
    [NativeHeader("Modules/Animation/Animator.h")]
    [NativeHeader("Modules/Animation/AnimatorController.h")]
    public sealed class AnimatorController : RuntimeAnimatorController
    {
        //
        // Summary:
        //     Constructor.
        public AnimatorController();

        //
        // Summary:
        //     The layers in the controller.
        public AnimatorControllerLayer[] layers { get; set; }
        //
        // Summary:
        //     Parameters are used to communicate between scripting and the controller. They
        //     are used to drive transitions and blendtrees for example.
        public AnimatorControllerParameter[] parameters { get; set; }

        public static AnimationClip AllocateAnimatorClip(string name);
        //
        // Summary:
        //     Creates an AnimatorController at the given path.
        //
        // Parameters:
        //   path:
        //     The path where the AnimatorController asset will be created.
        //
        // Returns:
        //     The created AnimationController or null if an error occured.
        public static AnimatorController CreateAnimatorControllerAtPath(string path);
        //
        // Summary:
        //     Creates an AnimatorController at the given path, and automatically create an
        //     AnimatorLayer with an AnimatorStateMachine that will add a State with the AnimationClip
        //     in it.
        //
        // Parameters:
        //   path:
        //     The path where the AnimatorController will be created.
        //
        //   clip:
        //     The default clip that will be played by the AnimatorController.
        public static AnimatorController CreateAnimatorControllerAtPathWithClip(string path, AnimationClip clip);
        //
        // Summary:
        //     This function will create a StateMachineBehaviour instance based on the class
        //     define in this script.
        //
        // Parameters:
        //   script:
        //     MonoScript class to instantiate.
        //
        // Returns:
        //     Returns instance id of created object, returns 0 if something is not valid.
        [FreeFunction("AnimatorControllerBindings::Internal_CreateStateMachineBehaviour")]
        public static int CreateStateMachineBehaviour(MonoScript script);
        //
        // Summary:
        //     Use this function to retrieve the owner of this behaviour.
        //
        // Parameters:
        //   behaviour:
        //     The State Machine Behaviour to get context for.
        //
        // Returns:
        //     Returns the State Machine Behaviour edition context.
        public static StateMachineBehaviourContext[] FindStateMachineBehaviourContext(StateMachineBehaviour behaviour);
        public static void SetAnimatorController(Animator animator, AnimatorController controller);
        //
        // Summary:
        //     The non-generic version of this method.
        //
        // Parameters:
        //   stateMachineBehaviourType:
        //     The type of state machine behaviour to add.
        //
        //   state:
        //     The AnimatorState to add the Behaviour to.
        //
        //   layerIndex:
        //     The layer index.
        [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
        public StateMachineBehaviour AddEffectiveStateMachineBehaviour(Type stateMachineBehaviourType, AnimatorState state, int layerIndex);
        public T AddEffectiveStateMachineBehaviour<T>(AnimatorState state, int layerIndex) where T : StateMachineBehaviour;
        //
        // Summary:
        //     Utility function to add a layer to the controller.
        //
        // Parameters:
        //   name:
        //     The name of the Layer.
        //
        //   layer:
        //     The layer to add.
        public void AddLayer(string name);
        //
        // Summary:
        //     Utility function to add a layer to the controller.
        //
        // Parameters:
        //   name:
        //     The name of the Layer.
        //
        //   layer:
        //     The layer to add.
        public void AddLayer(AnimatorControllerLayer layer);
        //
        // Summary:
        //     Utility function that creates a new state with the motion in it.
        //
        // Parameters:
        //   motion:
        //     The Motion that will be in the AnimatorState.
        //
        //   layerIndex:
        //     The layer where the Motion will be added.
        public AnimatorState AddMotion(Motion motion, int layerIndex);
        //
        // Summary:
        //     Utility function that creates a new state with the motion in it.
        //
        // Parameters:
        //   motion:
        //     The Motion that will be in the AnimatorState.
        //
        //   layerIndex:
        //     The layer where the Motion will be added.
        public AnimatorState AddMotion(Motion motion);
        //
        // Summary:
        //     Utility function to add a parameter to the controller.
        //
        // Parameters:
        //   name:
        //     The name of the parameter.
        //
        //   type:
        //     The type of the parameter.
        //
        //   paramater:
        //     The parameter to add.
        public void AddParameter(AnimatorControllerParameter paramater);
        //
        // Summary:
        //     Utility function to add a parameter to the controller.
        //
        // Parameters:
        //   name:
        //     The name of the parameter.
        //
        //   type:
        //     The type of the parameter.
        //
        //   paramater:
        //     The parameter to add.
        public void AddParameter(string name, AnimatorControllerParameterType type);
        public AnimatorState CreateBlendTreeInController(string name, out BlendTree tree);
        public AnimatorState CreateBlendTreeInController(string name, out BlendTree tree, int layerIndex);
        public T[] GetBehaviours<T>() where T : StateMachineBehaviour;
        //
        // Summary:
        //     Gets the effective state machine behaviour list for the AnimatorState. Behaviours
        //     are either stored in the AnimatorStateMachine or in the AnimatorLayer's ovverrides.
        //     Use this function to get Behaviour list that is effectively used.
        //
        // Parameters:
        //   state:
        //     The AnimatorState which we want the Behaviour list.
        //
        //   layerIndex:
        //     The layer that is queried.
        public StateMachineBehaviour[] GetStateEffectiveBehaviours(AnimatorState state, int layerIndex);
        //
        // Summary:
        //     Gets the effective Motion for the AnimatorState. The Motion is either stored
        //     in the AnimatorStateMachine or in the AnimatorLayer's ovverrides. Use this function
        //     to get the Motion that is effectively used.
        //
        // Parameters:
        //   state:
        //     The AnimatorState which we want the Motion.
        //
        //   layerIndex:
        //     The layer that is queried.
        public Motion GetStateEffectiveMotion(AnimatorState state);
        //
        // Summary:
        //     Gets the effective Motion for the AnimatorState. The Motion is either stored
        //     in the AnimatorStateMachine or in the AnimatorLayer's ovverrides. Use this function
        //     to get the Motion that is effectively used.
        //
        // Parameters:
        //   state:
        //     The AnimatorState which we want the Motion.
        //
        //   layerIndex:
        //     The layer that is queried.
        public Motion GetStateEffectiveMotion(AnimatorState state, int layerIndex);
        //
        // Summary:
        //     Creates a unique name for the layers.
        //
        // Parameters:
        //   name:
        //     The desired name of the AnimatorLayer.
        public string MakeUniqueLayerName(string name);
        //
        // Summary:
        //     Creates a unique name for the parameter.
        //
        // Parameters:
        //   name:
        //     The desired name of the AnimatorParameter.
        public string MakeUniqueParameterName(string name);
        //
        // Summary:
        //     Utility function to remove a layer from the controller.
        //
        // Parameters:
        //   index:
        //     The index of the AnimatorLayer.
        public void RemoveLayer(int index);
        //
        // Summary:
        //     Utility function to remove a parameter from the controller.
        //
        // Parameters:
        //   index:
        //     The index of the AnimatorParameter.
        public void RemoveParameter(int index);
        public void RemoveParameter(AnimatorControllerParameter parameter);
        public void SetStateEffectiveBehaviours(AnimatorState state, int layerIndex, StateMachineBehaviour[] behaviours);
        //
        // Summary:
        //     Sets the effective Motion for the AnimatorState. The Motion is either stored
        //     in the AnimatorStateMachine or in the AnimatorLayer's ovverrides. Use this function
        //     to set the Motion that is effectively used.
        //
        // Parameters:
        //   state:
        //     The AnimatorState which we want to set the Motion.
        //
        //   motion:
        //     The Motion that will be set.
        //
        //   layerIndex:
        //     The layer to set the Motion.
        public void SetStateEffectiveMotion(AnimatorState state, Motion motion, int layerIndex);
        //
        // Summary:
        //     Sets the effective Motion for the AnimatorState. The Motion is either stored
        //     in the AnimatorStateMachine or in the AnimatorLayer's ovverrides. Use this function
        //     to set the Motion that is effectively used.
        //
        // Parameters:
        //   state:
        //     The AnimatorState which we want to set the Motion.
        //
        //   motion:
        //     The Motion that will be set.
        //
        //   layerIndex:
        //     The layer to set the Motion.
        public void SetStateEffectiveMotion(AnimatorState state, Motion motion);
    }
}

根据定义RuntimeAnimatorController是runtime时Animator-Controller 的表现形式。所以在运行时,如果我们需要改变AnimatorController,就需要通过RuntimeAnimatorController Animator.runtimeAnimatorController来进行。这里的Animator-Controller包括AnimatorController和AnimatorOverrideController。 因为,AnimatorOverrideController和AnimatorController都是RuntimeAnimatorController的子类,所以RuntimeAnimatorController类型的变量可以同时引用这两种类型的Controller。

根据RuntimeAnimatorController的定义:运行时的Animator-Controller,以及上述的继承关系。我们可以这样认为,RuntimeAnimatorController类实现了动画控制器的内核,而其子类AnimatorController和AnimatorOverrideController继承了内核,并且定义了一些高层的概念和与之相关的外围api接口,从而对内核进行配置。 事实上,在运行期间(runtime),只存在RuntimeAnimatorController类型,而不存在AnimatorController类型和AnimatorOverrideController类型,但是RuntimeAnimatorController类型引用的实际对象只能是AnimatorController类型和AnimatorOverrideController类型的。正是因为,内核只能通过AnimatorController类型和AnimatorOverrideController类型对象提供的外围api接口进行配置。在运行时,我们只需要这个配置好的内核,所以自然我们只需要RuntimeAnimatorController类型。

比如AnimatorController类增加了一些概念:Layer,parameters,transition,BlendTree等,借助于这些抽象的高层概念,就可以以实现在EditWindow进行可视化的基于节点的编辑,以便创建一个数据asset,或者又被称为序列化的AnimatorController对象。然后在deserialization阶段,就会创建一个对应的AnimatorController对象,并且由这个数据asset初始化相应的状态(字段),再由外围api接口处理这些状态字段从而对内核本身进行配置。

同理对于AnimatorOverrideController类来说,其也增加了一些概念,比如需要被覆写的RuntimeAnimatorController,以及一个AnimationClipPair[] 数组指定了RuntimeAnimatorController中由哪些动画需要被覆盖(原动画----> ()),从而以该RuntimeAnimatorController为蓝本,对自身继承来的内核进行配置。 借助于上述概念,当我们创建一个数据asset时(即AnimatorOverrideController),就相当于创建了一个配置文件,也称为序列化的AnimatorOverrideController对象。但是这个数据asset在Asset面板被指定的动画控制器只能是AnimatorController类型的。只不过在runtime,通过deserialization的特定机制,其会被RuntimeAnimatorController类型所引用。

在Inspector面板中,Animator组件的第一个属性就是Controller(类型是RuntimeAnimatorController),我们可以由此指定一个Animator-Controller的asset,包括AnimatorController和AnimatorOverrideController。但是我们必须明白,在Editor中的操作都是对序列化数据(对象)的操作。也就是说,在这种情况下,Animator组件和和Animator-Controller都是一种序列化的对象表示形式。当项目实际运行在内存中时(Runtime时),Unity就会进行反序列化(deserialization),也就是根据序列化的数据创建具体的对应的C#对象,比如根据序列化的Animator组件生成一个对应的Animator对象,于是我们就可以根据GetComponent方法去获取这个C#对象 。同时,由于我们通过序列化的Animator组件在场景中引用了序列化的Animator-Controller资源(asset),所以Unity还会反序列化这个asset,生成一个对应的C#对象——AnimatorController类的实例或者AnimatorControllerOverride类的实例。只不过在运行时,这两种类型的实例都是被RuntimeAnimatorController类型的变量所引用。