Unity animator:StateMachineBehaviour的一点应用(施工中)

Unity animator:StateMachineBehaviour的一点应用(施工中)

有什么用

直奔主题,我们先讲讲作用,用法,再慢慢解释

一个简单的应用场景:Unity动画状态机中有一个“特色”是,如果你为一组Animator添加一个triggerA的parameter,用于控制动画A的播放(这里我们举例triggerA触发一次,进入动画A播放一次),你会发现,快速出发两次或多次triggerA,不加入限制条件,动画A将再播放完后再播放一次或多次

已有的解决方案是在脚本中添加一个计时器,控制triggerA的触发频率。但是通过重写StateMachineBehaviour的几个OnState方法,让动画每次在你需要的时候(进入,Update,退出等)清空一次这个输入信号(或是其他操作),便可以更方便,系统的控制这些信号

例如以下是我用于清空输入信号的FSMClearSignals,根据需要,我重写了OnStateEnter和OnStateExit,方便我在进入和退出被挂载的动画状态的时刻,清空之前的输入信号

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

public class FSMClearSignals : StateMachineBehaviour
{
    public string[] clearAtEnter;
    public string[] clearAtExit;

    // 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)
    {
        foreach (var signal in clearAtEnter)
        {
            animator.ResetTrigger(signal);
        }
    }

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //
    //}

    // 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)
    {
        foreach (var signal in clearAtExit)
        {
            animator.ResetTrigger(signal);
        }
    }

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}   

实现原理

StateMachineBehaviour具有一个当动画从进入到播放完毕退出的生命周期,通过重写以下的5个方法,你可以轻松的控制动画的各种状态回调,以上的代码只是一个简单的应用

  • OnStateEnter()
  • OnStateUpdate()
  • OnStateExit()
  • OnStateMove()
  • OnStateIK()

图片

个人的用法

我们现在需要的动画状态下新建一个脚本,它会自动继承StateMachineBehaviour

图片

除了上文所示的FSMClearSignals,出于个人的使用需求,我还建立了三个脚本文件用于向状态机外传送状态信息,分别是

  • FSMOnEnter.cs
  • FSMOnUpdate.cs
  • FSMOnExit.cs

在这个三个脚本中我分别只重写了OnStateEnter(),OnStateUpdate(),OnStateExit()

每个脚本中我都建立了一个string数组public string[] onEnterMessages; 存储我需要发送的信息,例如我

public class FSMOnEnter : StateMachineBehaviour
{
    public string[] onEnterMessages;

    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        foreach (var msg in onEnterMessages)
        {
            //animator.gameObject.SendMessage(msg);
            animator.gameObject.SendMessageUpwards(msg);
        }
    }
}

图片

这是每当我进入一次Jump状态,我的FSMOnEnter脚本就会给上级传出一个OnJumpEnter的信息,当然我还需要一个拦截,接收信息的方法,我把他写入在控制我的主角的脚本下

public void OnJumpEnter () {
        thrustVec = new Vector3 (0, jumpVelocity, 0);
        playerInput.inputEnabled = false;
        lockPlane = true;
        trackDirection = true;
    }

可以看到我在这个方法里实现了跳跃速度,方向的控制,跳跃时的输入锁定。这样一来每当觉得进入一次Jump状态,OnJumpEnter方法就会执行。个人感觉是比之前用协程计时器计算CD而言,系统了不少,也方便了后期团队成员的更多调用。

原文地址:https://www.cnblogs.com/zhxmdefj/p/10714230.html

时间: 2024-11-12 17:49:41

Unity animator:StateMachineBehaviour的一点应用(施工中)的相关文章

Unity 2D游戏开发教程之游戏中精灵的跳跃状态

Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却无法从低的地面移动到高的地面,因为当前的游戏精灵只能左右移动,即left和right.为了解决这个问题,本节就来为精灵添加跳跃状态.   图2-14  精灵从一个地面移动到另一个地面 (1)如果要为精灵添加跳跃状态,即jump,就不得不再引入其它状态: q   landing:用于表示精灵接触到地面

母函数入门笔记(施工中…

定义:对于一个数列,它的母函数(即生成函数)为   为了对这个准确求值,我们设    举一个简单的例子 例1 对于数列 他的生成函数为 ,那么应用一下等比数列求和公式 这里由于 所以当时 那么   例2 对于数列 生成函数 就是上面那个的比例系数放大到b 那么就是 例3 对于数列 生成函数 就是比例系数放大到 可以得出 类比可以得到   例4 然后是一个很鬼的 对于数列求生成函数 我们考虑这个东西是在无限定义下的 所以等价于 例5 然后是一个稍微麻烦点的 对于数列求生成函数   然后为了把这个东

The C Programming Language(K&R) 扣细节随记(施工中...

各种糟糕,入坑这么久才开始看K&R的The C Programming Language学C,而且还是为了应付开学某场滚回本体的考试(虽然觉着即使复习了还会被各种吊打),废话不多说,开始施工.? ? |--> 导言 整数除法会执行舍位,故要先乘后除. 数据类型: 关键字 位长(字节) 范围 格式化字符串 char 1 bytes -128..127(或0..255,与体系结构相关) ?%c unsigned char 1bytes 0..255 ?%c,?%hhu signed char 1

Unity Animator动画状态机 深入理解(一)

接触Unity以来就已经有了Animator,Animation用的少,不过也大概理解他俩之间的一个区别于联系. 图中其实就是Animator和Animation之间的区别于联系了,啊!你肯定会告诉我这就不是Animator么. 对啊,Animator其实是由Animation组成的.比如在Animator没有出现的时候有些公司写的动画状态机其实就是代码版的Animator. Animator其实就是把Animation统一管理和逻辑状态管理的组件,而Animation就是每一个动画. 动画状态

【Unity Shaders】Reflecting Your World —— Unity3D中的法线贴图和反射

http://blog.csdn.net/candycat1992/article/details/24541623 本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ==================================

Animator系统运用在实际项目中的一些问题

1.Q:公用状态机还是单独配置状态机? A:村民之类的角色可以公用状态机,Unity有一个Animator Override Controller(Project面板下,右键创建里).用这个来重写公用状态机的动画文件. 而主角没办法,只能单独配置状态机,最后策划在表里填写用哪一个控制器文件,控制器文件可以经过Resource载入 2.Q: 位移如何通过状态机的变量而改变长度? A:我之前一直在思考这个问题,因为游戏中可能你角色力量值高一些,位移就长一些.后来觉得可以用混合树解决这个问题, 混合树

[施工中]Cairo教程

本文为Cairo官方教程的翻译 原英文链接:http://cairographics.org/tutorial/ 有任何翻译错误请为我指正. 转载请注明原文链接. [正在施工!] Cairo教程 本教程来自Michael Urman的cairo tutorial for python programmers.原来的代码片段已经被翻译成C,有必要改的地方已经被改过了. Cairo是一个强大的2D图形库.本文将向您介绍Cairo如何工作,很多人都会用它来编写图形应用. 为了在您计算机上进行工作,需要

unity, animator stateMachine立即触发状态转换

例如按下键jump按钮人物执行跳起动作,同时动画状态由idle转换为jump,同时打开Game窗口和Animator窗口对比观察,发现人物跳起时动画状态并没有同步发生转换,而是有一定延迟,导致人物动画与动作脱节.后来发现是由于Transition(idle->jump)面板中勾选了Has Exit Time造成的,把此勾去掉就同步了. 关于Has Exit Time参考:http://docs.unity3d.com/Manual/class-Transition.html

unity学习--003:角色控制器(中)

在上篇 unity学习--003:角色控制器(上)中,看了点角色控制的基本实现方法,鼠标和键盘控制比较粗糙的实现. 在这篇中,主要介绍几个unity封装的角色控制方法, 然后预计在下篇中综合介绍几种主流的角色控制方法. 话不多说,开搞: 依旧是上次拖过来的几个模型 不过,这次添加了地形,素材,和天空盒,自然光,至于怎么加的,请看这里 添加地形等 不在黑黑的,心情也好点了,下面来介绍几种unity自带的角色控制操作.(这些方法都是unity自带的API) 1.CharacterController