64.3D动画状态机行为脚本

64.3D动画-状态机行为脚本


64.1 知识点

状态机行为脚本是什么

  • 状态机行为脚本是一类特殊的脚本,继承指定的基类,主要用于关联到状态机中的状态矩形上。
    我们可以按照一定规则编写脚本,在进入、退出、保持在某一个特定状态时进行逻辑处理。
    简单解释就是为 Animator Controller 状态机窗口中的某一个状态添加一个脚本,利用这个脚本我们可以做一些特殊功能,比如:
    • 进入或退出某一状态时播放声音
    • 仅在某些状态下检测一些逻辑,比如是否接触地面等等
    • 激活和控制某些状态相关的特效

如何使用状态机脚本

新建一个脚本继承 StateMachineBehaviour 基类

实现其中的特定方法进行状态行为监听

  • OnStateEnter: 进入状态时,第一个 Update 中调用
  • OnStateExit: 退出状态时,最后一个 Update 中调用
  • OnStateIK: OnAnimatorIK 后调用
  • OnStateMove: OnAnimatorMove 后调用
  • OnStateUpdate: 除第一帧和最后一帧,每个 Update 上调用
  • OnStateMachineEnter: 子状态机进入时调用,第一个 Update 中调用
  • OnStateMachineExit: 子状态机退出时调用,最后一个 Update 中调用

处理对应逻辑

代码相关:
// 重写该函数,当进入指定状态时调用
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    // 当前状态名称与所需状态名称相同时输出日志
    if (stateInfo.IsName(stateName))
        Debug.Log("进入HumanoidIdle状态");
}

// 重写该函数,当退出指定状态时调用
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    // 当前状态名称与指定名称相同时输出日志
    if (stateInfo.IsName("HumanoidIdle"))
        Debug.Log("退出HumanoidIdle状态");
}

// 重写该函数,当进行动画 IK 计算时调用
public override void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    base.OnStateIK(animator, stateInfo, layerIndex);
}

// 重写该函数,当进行动画更新时每帧调用
public override void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    base.OnStateMove(animator, stateInfo, layerIndex);
}

// 重写该函数,当进行动画更新时每帧调用
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    base.OnStateUpdate(animator, stateInfo, layerIndex);
    // 当前状态名称为指定名称时输出日志
    if (stateInfo.IsName("HumanoidIdle"))
        Debug.Log("处于HumanoidIdle状态");
}

// 重写该函数,当进入状态机时调用
public override void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
{
    base.OnStateMachineEnter(animator, stateMachinePathHash);
}

// 重写该函数,当退出状态机时调用
public override void OnStateMachineExit(Animator animator, int stateMachinePathHash)
{
    base.OnStateMachineExit(animator, stateMachinePathHash);
}
添加脚本
可以添加变量在外面配置,注意在动画播放到特殊时期时处理逻辑

状态机行为脚本和动画事件如何选择

  • 状态机行为脚本相对动画事件来说更准确,但是使用起来稍微麻烦一些。根据实际需求选择使用。

64.2 知识点代码

Lesson64_3D动画_状态机行为脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson64_3D动画_状态机行为脚本 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 状态机行为脚本是什么?
        //状态机行为脚本时一类特殊的脚本,继承指定的基类
        //它主要用于关联到状态机中的状态矩形上
        //我们可以按照一定规则编写脚本
        //当进入、退出、保持在某一个特定状态时我们可以进行一些逻辑处理
        //简单解释就是为Animator Controller状态机窗口中的某一个状态添加一个脚本
        //利用这个脚本我们可以做一些特殊功能
        //比如
        //1.进入或退出某一状态时播放声音
        //2.仅在某些状态下检测一些逻辑,比如是否接触地面等等
        //3.激活和控制某些状态相关的特效
        #endregion

        #region 知识点二 如何使用状态机脚本
        //1.新建一个脚本继承StateMachineBehaviour基类
        //2.实现其中的特定方法进行状态行为监听
        //  OnStateEnter    进入状态时,第一个Update中调用
        //  OnStateExit     退出状态时,最后一个Update中调用
        //  OnStateIK       OnAnimatorIK后调用
        //  OnStateMove     OnAnimatorMove后调用
        //  OnStateUpdate   除第一帧和最后一帧,每个Update上调用
        //  OnStateMachineEnter     子状态机进入时调用,第一个Update中调用
        //  OnStateMachineExit      子状态机退出时调用,最后一个Update中调用
        //3.处理对应逻辑
        #endregion

        #region 知识点三 状态机行为脚本和动画事件如何选择
        //状态机行为脚本相对动画事件来说更准确
        //但是使用起来稍微麻烦一些

        //根据实际需求选择使用
        #endregion
    }

}

Lesson64_3D动画_状态机行为脚本StateMachineBehaviour

// 引入命名空间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 定义脚本类并继承StateMachineBehaviour
public class Lesson64_3D动画_状态机行为脚本StateMachineBehaviour : StateMachineBehaviour
{
    // 声明公共字符串变量stateName表示状态名称
    public string stateName;

    // 声明公共字符串变量musicName表示音乐名称
    public string musicName;


    //  OnStateEnter    进入状态时,第一个Update中调用
    //  OnStateExit     退出状态时,最后一个Update中调用
    //  OnStateIK       OnAnimatorIK后调用
    //  OnStateMove     OnAnimatorMove后调用
    //  OnStateUpdate   除第一帧和最后一帧,每个Update上调用
    //  OnStateMachineEnter     子状态机进入时调用,第一个Update中调用
    //  OnStateMachineExit      子状态机退出时调用,最后一个Update中调用


    // 重写该函数,当进入指定状态时调用
    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        // 当前状态名称与所需状态名称相同时输出日志
        if (stateInfo.IsName(stateName))
            Debug.Log("进入HumanoidIdle状态");
    }

    // 重写该函数,当退出指定状态时调用
    public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        // 当前状态名称与指定名称相同时输出日志
        if (stateInfo.IsName("HumanoidIdle"))
            Debug.Log("退出HumanoidIdle状态");
    }

    // 重写该函数,当进行动画IK计算时调用
    public override void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        base.OnStateIK(animator, stateInfo, layerIndex);
    }

    // 重写该函数,当进行动画更新时每帧调用
    public override void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        base.OnStateMove(animator, stateInfo, layerIndex);
    }

    // 重写该函数,当进行动画更新时每帧调用
    public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        base.OnStateUpdate(animator, stateInfo, layerIndex);
        // 当前状态名称为指定名称时输出日志
        if (stateInfo.IsName("HumanoidIdle"))
            Debug.Log("处于HumanoidIdle状态");
    }

    // 重写该函数,当进入状态机时调用
    public override void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
    {
        base.OnStateMachineEnter(animator, stateMachinePathHash);
    }

    // 重写该函数,当退出状态机时调用
    public override void OnStateMachineExit(Animator animator, int stateMachinePathHash)
    {
        base.OnStateMachineExit(animator, stateMachinePathHash);
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏