关于Unity中Mecanim动画的动画状态代码控制与代码生成动画控制器

2023-11-15

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

 

 

动画状态代码控制

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.把Assets\Animations\AnisForFight的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)到Assets\Animations目录下,里面有十个动画

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);//状态机添加动画状态
            // 这个语句相当于把Assets\Animations\AnisWithNum目录下的一个一个的可执行动画文件关联到对应的动画状态的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属性中。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于Unity中Mecanim动画的动画状态代码控制与代码生成动画控制器 的相关文章

  • 为什么 int8_t 和用户通过 cin 输入显示奇怪的结果[重复]

    这个问题在这里已经有答案了 一小段代码让我发疯 但希望你能阻止我跳出窗外 看这里 include
  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 为什么极端下派生类(多重虚拟继承)的大小包括超类成员大小的两倍?

    include
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 由 IHttpClientFactory 注入时模拟 HttpClient 处理程序

    我创建了一个自定义库 它会自动为依赖于特定服务的 Polly 策略设置HttpClient 这是使用以下方法完成的IServiceCollection扩展方法和类型化客户端方法 一个简化的例子 public static IHttpClie
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 使用 %d 打印 unsigned long long

    为什么我打印以下内容时得到 1 unsigned long long int largestIntegerInC 18446744073709551615LL printf largestIntegerInC d n largestInte
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且
  • 我的班级应该订阅自己的公共活动吗?

    我正在使用 C 3 0 遵循标准事件模式我有 public event EventHandler

随机推荐

  • 西安电子科技大学第二届程序设计新生赛-F-zxy的长跑【欧拉回路】

    题目链接 好极了的欧拉回路 我们想知道怎样才能跑完所有的边 我们可以从度为奇数的点出发 因为这是欧拉回路的无向图的先觉调节 当然 这道题还有另外一种可能就是这是一个环 1 gt 2 2 gt 3 3 gt 4 4 gt 1 那么就没有奇数度
  • 《java开发高频面经总结大合集》你想要的都在这里了

    前言 很多人说到面试 头一下就大了 各种不自信 是实力不够还是信心不够 面试除了你平时不断积累实力 另一方面也需要讲究面试方法和技巧 我特别喜欢一句话 不打没有准备的战 为帮助开发者们提升面试技能 有机会入职BAT等大厂公司 所以 我采访了
  • 100流明相当于多少w_1990年的100元,相当于2020年的多少钱?

    1990年距今已经30年了 可以说我国是发生了翻天地覆的变化 不管是从经济水平还是老百姓的收入水平都是这样 在80年代的时候 也许 万元户 代表的就是 有钱人 而到了90年代 家庭财富超过万元的已经可以说是比较多了 起码相比80年代来说的话
  • 2023华为OD机试真题【施肥问题】

    解题思路 首先需要计算每个果园的施肥时间 即果园面积除以施肥机能效 然后找到最小的施肥机能效 保证施肥任务能在规定时间内完成 如果施肥天数小于果园数量 则无法完成施肥任务 返回 1 如果施肥天数等于果园数量 则直接返回最大果园面积 对果园面
  • 汇编语言实现跑马灯 8051单片机

    通过一位 F 的16进制 转换为 2进制的 1111 然后移动一位 有三极管开关所改变 0的时候发光 1的时候变暗 所以一开始0FFH表示高8位为0 低8位为1111 1111 表示全暗 然后右移变为1111 1110亮第一个等 之后类推
  • 推荐这款神器!每年都有数以百万的大学生想用它!闲鱼都卖两百!

    文末有下载链接 如同明日将死那样生活 如同永远不死那样求知 甘地 image 这是一个能把破解者气死的软件 辛辛苦苦破解的软件 却被别人拿去收费标价200元 真买了 吃亏的是你 在我这 不用钱 说到论文翻译 真的是让人抓狂 每年百万的大学生
  • 【stm32】wifi ESP8266的透传 实验二(HAL库开发)

    一 总算完成了透传 感觉没几行代码 就是在昨天的基础上 对ESP8266的AT指令进行了封装 什么选择工作模式 STA 还是 AP 查询附近WIFI热点 连接WIFi 见解服务器的IP和端口 开启透传 我的代码的缺点 1 有点简单粗暴 逻辑
  • 教你使用gitee+PicGo+typora搭建免费的Markdown图床

    文章目录 创建gitee仓库 设置私人令牌 下载PicGo typora设置 测试时出错可能原因 注意 gitee添加了防盗链 屏蔽外链访问 注意 gitee添加了防盗链 屏蔽外链访问 注意 gitee添加了防盗链 屏蔽外链访问 现使用阿里
  • [西湖论剑2021中国杭州网络安全技能大赛]Yusa的秘密 writeup

    西湖论剑2021 Yusa的秘密 Sakura组织即将进攻地球 此时你意外得到了该组织内某个成员的电脑文件 你能从中发现本次阴谋所用的关键道具吗 注 题目中包含了五个彩蛋 且彩蛋对解题本身没有任何影响 快去发现吧 附件 Who am I z
  • 【数据结构】图文详解11道力扣链表OJ题

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 一 移除链表元素 二 反转链表 三 链表的中间节点 四 链表中倒
  • 【H5】 实现调用相机拍照功能

    H5 实现调用相机拍照功能 效果图如下 实现代码如下
  • Qt中线程的使用1

    初学Qt线程 此实例只是对Qt单一线程的使用 另外结合信号槽实现ui界面与子线程之间数据的传输 可以解决线程在运行的过程中 关闭对话框程序崩溃的问题 此实例要实现的效果图如下 界面控件的类 对象表如下 界面启动后 起初停止线程按钮是置灰的
  • Web的基本漏洞--代码执行漏洞RCE

    目录 一 代码执行漏洞的介绍 1 代码执行漏洞的原理 2 常用含有的代码执行漏洞的函数 3 代码执行漏洞的危害 4 代码执行漏洞的防范措施 一 代码执行漏洞的介绍 1 代码执行漏洞的原理 web应用程序是指程序员在代码中使用了一些执行函数例
  • Nilpotent

    In mathematics an element displaystyle x x of a ring displaystyle R R is called nilpotent if there exists some positive
  • 使用java进行补零操作

    很多情况下都会用到补零操作 譬如说工号01 0003什么的 以下代码用for循环和while循环实现简单的补零操作 在数字之前补零 可以补一个零 也可以补多个零 public class AddZero public static void
  • BaseMultiItemQuickAdapter实现多布局拖拽排序

    前言 BaseMultiItemQuickAdapter默认是支持但单布局拖拽功能的 如BaseItemDraggableAdapter 但是无法满足多布局拖拽需求 需要加以改造 1 梳理继承关系及构造 通过下图 可以发现BaseMulti
  • ArcObjects中的GraphicsLayer---------元素的容器

    图形元素 Graphic Element 是存储于GraphicsLayer中的 本文主要涉及的接口和类主要有以下几种 IGraphicsContainer IGraphicsLayer ICompositeGraphicsLayer Gr
  • SSM框架的科普有毒蘑菇网站系统源码+数据库+完整安装视频

    项目名称 SSM框架的科普有毒蘑菇网站系统源码 视频效果 SSM框架的科普有毒蘑菇网站系统源码 系统说明 用户测试账号 test 123456 管理员测试账号 admin 123456 数据库每个表都有详细注释 代码也有详细注释 详细说明
  • HTML基本语法格式(元素、标签)

    HTML的语法格式 阅读提醒 由于博客显示问体所以元素的 lt gt 开始和 gt 被省略了 HTML的主体格式 第一部分 和是网页文件的最外层标签 HTML中所有的内容都要在这里面 第二部分 和标签之间文本是头信息 放在元素的最上面使用
  • 关于Unity中Mecanim动画的动画状态代码控制与代码生成动画控制器

    对于多量的 复杂的 有规律的控制器使用代码生成 动画状态代码控制 1 每个动画状态 比如进入状态 离开状态 等都有可能需要代码来参与和处理 比如 进入这个动画单元后做哪些事情 来开这个动画单元后做哪些事情 为了解决这个问题 unity允许每