zoukankan      html  css  js  c++  java
  • 关于Unity中Mecanim动画的动画状态代码控制与代码生成动画控制器

    对于多量的、复杂的、有规律的控制器使用代码生成

    动画状态代码控制

    1:每个动画状态,比如进入状态,离开状态, 等都有可能需要代码来参与和处理,比如,进入这个动画单元后做哪些事情,来开这个动画单元后做哪些事情,为了解决这个问题,unity允许每个动画单元来绑定一个脚本代码,这个脚本代码必须继承于StateMachineBehaviour;
    2: 可以在动画状态的Add Behaviour上添加挂载一个脚本到动画状态;
    3: StateMachineBehaviour主要接口:
      (1)OnStateEnter: 当动画开始播放的时候被调用;
      (2)OnStateExit: 当动画结束播放的时候被调用;
      (3)OnStateMove: 当动画被移动的时候调用;
      (4)OnStateIK: 当动画触发逆向运动学时调用此方法;
      (5)OnStateUpdate: 每帧都会被调用;


    动画状态代码控制案例

    1.创建Unity工程和文件目录

    2.导入资源文件包body_anim.unitypackage(第58)

    3.打开Models文件夹,点击模型Boy,设置Rig---->Animation Tyoe---->Humanoid(人形动画)

    4.配置Avatar

    5.把模型Boy拖进场景中,会自己挂载一个Animator的组件

    6.在res文件夹下创建一个动画控制器Create---->Animator Controller,叫做anim_ctrl,双击打开,可以用鼠标中键按下拖动背景

    7.把AssetsAnimationsAnisForFight的Boy@ForwardKick.FBX直接拖进Animator视图中的状态机中,设置为默认,再连接一条线到Exit

    8.把anim_ctrl关联到Boy模型的Animator组件的Controller

    9.运行,角色会不停地踢腿,现在我们要给它加一个代码控制

    10点击状态机里面的ForwardKick,右边属性面板下有一个Add Behaviour,点击创建一个新的脚本叫anim_test。

    11.这时候anim_test脚本文件在文件目录的外面,我们可以把它拖进scripts文件夹

    打开脚本anim_test

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class anim_test : StateMachineBehaviour {
    
        //layerIndex就是动画所在的层,Base Layer层的layerIndex是0
        //要获得其他节点的组件都可以像MonoBehaviour那样做
         // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
        override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
            Debug.Log("OnStateEnter");
        }
    
        //每一帧都执行
        // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
        override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
            Debug.Log("OnStateUpdate");
        }
    
        // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
        override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
            Debug.Log("OnStateExit");
        }
    
        //下面两个用的不多
        // OnStateMove is called right after Animator.OnAnimatorMove(). Code that processes and affects root motion should be implemented here
        //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
        //
        //}
    
        // OnStateIK is called right after Animator.OnAnimatorIK(). Code that sets up animation IK (inverse kinematics) should be implemented here.
        //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
        //
        //}
    }

    代码生成动画控制器

    1:10个状态,每2个状态之间需要建立两两的联系,那么这个动画控制器就会有100个过渡条件,那么这个时候最好的方式是代码自动的生成动画控制器;
    2: 扩展编辑器,来动态生成这个动画控制器,不用手动的去修改;
    3: 扩展编辑器的相关的API:
      (1)创建一个动画控制器:createAnimationControllerAtPath(“path”);
      (2)获取动画状态机: AnimatorStateMachine controller.layers[index].stateMachine;
      (3)设置默认的动画状态: stateMachine.defaultState
      (4)加载AnimationClip: AssertDatabase.LoaderAssetAtPath(“path”, typeof(AnimationClip))
          As AnimationClip;
      (5)为每个状态指定动画:state.motion = animclip;
      (6)AnimController.AddParameter(名字, AnimationParamsType);
      (7)添加一个过渡: AddTransition(dst_state, false);
      (8)过渡添加一个条件: trans.AddCondition();
      (9)最后一个添加exit state: AddExitTransition(); 制定输出动画;

    代码生成动画控制器案例

    1.先导入动画资源包anims.unitypackage(第58)到AssetsAnimations目录下,里面有十个动画

    2.扩展编辑器,新建一个Editor文件夹,在Editor目录下创建一个脚本叫CreateAnimCtrl

    打开CreateAnimCtrl

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    using UnityEditor.Animations;
    
    public class CreateAnimCtrl : MonoBehaviour {
        [MenuItem("Assets/Create/CreateAnimCtrl")]//添加了一个菜单栏,可以在最上面菜单栏点击Assets/Create发现多了一个CreateAnimCtrl
        // 执行函数,点击Assets/Create/CreateAnimCtrl会执行的函数
        static void Run() {
            Debug.Log("Run called");
            // Step1: 生成我们的动画控制文件;这个操作等于右键Create---->Animator Controller到Assets/res目录下,名字叫code_anim.controller
            AnimatorController ctrl = AnimatorController.CreateAnimatorControllerAtPath("Assets/res/code_anim.controller");
            // Step2 获取我们的动画状态机;
            AnimatorStateMachine state_machine = ctrl.layers[0].stateMachine;
    
            // 创建我们的动画状态;先创建一个数组,里面可以放10个动画状态
            AnimatorState[] state = new AnimatorState[10] ;
            for (int i = 0; i < 10; i++) {
                state[i] = state_machine.AddState("state" + i);//状态机添加动画状态
                // 这个语句相当于把AssetsAnimationsAnisWithNum目录下的一个一个的可执行动画文件关联到对应的动画状态的Motion属性
                // as 强转类型过去,是C#的语法
                AnimationClip anim = AssetDatabase.LoadAssetAtPath("Assets/Animations/AnisWithNum/Ani" + i + ".FBX", typeof(AnimationClip)) as AnimationClip;
                state[i].motion = anim;
            }
    
            // 两两添加过渡;
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 10; j++) {  // i --> j 的transform
                    // 创建每个动画过渡的控制变量,等于在Animator面板的Parameters面板下的参数添加条件变量,是开关类型的变量,这个变量就是只要选中就会执行
                    ctrl.AddParameter(i + "switch" + j, AnimatorControllerParameterType.Trigger);
                    // end 
                    //两两动画状态之间添加过渡,等于在状态机那个图里面选择一个动画状态然后右键Make Transition
                    AnimatorStateTransition trans = state[i].AddTransition(state[j], false);
    
                    //给每个过渡添加条件,等于在过渡的属性面板下面的Condition属性点击+号,默认是0,就是关闭的状态
                    trans.AddCondition(AnimatorConditionMode.If, 0, i + "switch" + j);
                }
            }
                // end 
            // 设置一个默认动画状态,把第0个动画状态设置为默认动画状态;
            state_machine.defaultState = state[0];
    
        }
    }

    3.点击Assets/Create/CreateAnimCtrl,自动生成动画控制器且配置好了。最后把code_anim.controller关联到Boy模型的Animator组件的Controller属性中。

  • 相关阅读:
    ffmpeg——压缩mav格式音频
    java控制台编译通过,运行出现找不到或无法加载主类的情况
    “Hello World!”团队——Final发布用户使用报告
    PSP总结报告
    软工第十二周个人PSP
    “Hello World!”团队第七周召开的第一次会议
    个人第十一周PSP
    互评Beta版本—博客园安卓APP
    sqlalchemy 学习笔记
    sqlite学习笔记
  • 原文地址:https://www.cnblogs.com/HangZhe/p/7264411.html
Copyright © 2011-2022 走看看