Unity游戏开发之游戏动画(Unity动画系统)

news2024/9/29 15:34:41

文章目录

  • Unity动画系统
    • 动画片段 Animation Clip
      • 在Unity中制作动画
      • 动画复用
    • 替身系统 Avatar
    • Animator 组件 Animator Component
    • 动画状态机 Animator Controller
      • 动画状态
        • 动画状态的类型
        • 动画状态的属性
      • 动画状态机----动画转换
        • 转换属性的配置面板
  • 、、、、

Unity动画系统

Unity动画系统分为

  • 动画片段 Animation Clip: 动画资源,与模型无关
  • 动画状态机 Animator Controller:帮助我们跟踪当前动画的播放状态,并且根据设置觉得如何切换动画片段
  • 动画组件 Animator Component:玩家角色需要播放动画功能时,需要动画组件,将游戏对象需要的动画状态机(以及替身)放入该组件,之后便可以在游戏脚本中自由访问该组件,从而自由控制游戏对象动画。
  • 替身 Avatar:人形动画骨骼的标准,所有按照同一标准配置好的人形角色都可以播放同一套动画。

动画片段 Animation Clip

在Unity中制作动画

  1. 点击Window,打开animatioin窗口
  2. 选中需要制作动画的物体,点击create,选择一个位置保存。
    Unity为我们在保存位置生成了一个动画片段(.anim) 文件和一个pivet 动画状态机(.controller),
    并且,在需要制作动画的物体上挂在了一个 Animator组件

注:动画片段文件(.anim)是使用标记语言YAML编写的文件(Unity中绝大多数文件都是使用YAML来记录的)

  1. 选中物体,切换到Animation视图,选中这里的add Property,选择要对哪些属性进行变换
    在这里插入图片描述
  2. 时间标尺的默认长度为1s,在起始位置0s和结束位置1s处各有一个关键帧。
  3. 选择对应的关键帧,或在任意位置修改数据,即可创建关键帧。修改关键帧后,中间的帧可根据两边关键帧插值计算得到。
    在这里插入图片描述
  4. 点击左下角的Curves,我们就能已曲线的形式观察并修改当前的动画片段
  5. 打开动画片段文件(.anim),在检视视图下看到Euler:1,说明包含一段欧拉角运动。
    在这里插入图片描述

动画复用

当动画文件只对应一个物体的时候,可以复用到任何一个物体上。

当动画文件要处理多个物体或多个游戏对象时,会在文件中写上该物体的对象名称,unity会通过文件里的这个名称找到正确的游戏对象。
如果游戏对象的名字和动画文件中的不一致,就无法正常播放。

动画复用,当骨骼结构一致,命名也一致,就可以对动画文件进行复用。

当骨骼结构相似,但动画命名不一致时,修改命名以及骨骼系统就可以复用动画,但Unity对人形骨骼有简便的处理方式:Avator

替身系统 Avatar

当两个角色的命名方式不一样时,动画不能复用。
如下:名称不匹配,会在Animation窗口显示Missing!
在这里插入图片描述
使用替身系统,需要为两个模型都添加替身,使得两模型替身命名方式相同。

  1. 模型创建Avatar,对所有模型创建,并可在Avatar配置中对模型的修改量进行参数设置。具体可看【Unity动画系统详解 四】八分钟理解并掌握Avatar和人形动画复用【Unity开发入门教程12】 5:05
  2. 对A模型的动作配置A模型的Avatar,对B模型的动作配置B模型的Avator。
  3. 新建Animator Controller,在动画状态机中添加动作。
  4. 对场景中的角色模型添加Animator组件,不同的模型选择不同的Avatar,但可以共用相同的动画状态机。

Animator 组件 Animator Component

  • Controller 动画状态机
  • Avatar 替身系统:在组件这里,还担任了一个传令兵的职责,会在当前对象以及子对象中层层寻找符合要求的模型。
  • Apply Root Motion:有些动画自带位移,如果希望动画位移应用在游戏上,则勾选。
  • update mode:动画的刷新模式(重新计算每个骨骼结点的位置转向和缩放的数值)
    • normal:和帧率同步(update())
    • Animate Physics:与物理引擎同步(fixedUpdate())
    • Unscaled Time:和帧率同步,但会忽略时间标尺,及当修改时间标尺(游戏中1s对应现实2s,则Unscaled Time不受影响)
  • Culling Mode 剔除模式: 当游戏对象没有被看到时,如何处理
    • Always Animate : 动画不受影响
    • Cull Update Transforms:剔除关于IK之类的操作
    • Cull Completely:完全停止动画

动画状态机 Animator Controller

动画状态

动画状态的类型

  • 单独的动画片段

添加单独动画片段的三种方法
1. 新建空状态,再添加动画
2. 选中动画,右键添加
3. 直接拖动动画

  • 多个动画片段组成的混合书 Blend Tree
  • 另一个动画状态机

动画状态的属性

  1. 名称:修改状态机中展示的文本,以便管理
  2. 标签Tag:给不同的动画状态打上标签进行分类,可在脚本中便于统一管理
//获取当前状态机正在播放的动画状态
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(animator.GetLayerIndex("层级名称"));
//通过标签对不同的标签动画,做不同的事
if(stateInfo.isTag("标签名称")){
	......
}
  1. Motion :动画片段或混合树
  2. Speed:动画的播放速度(不能通过脚本更改)
  3. Multiplier:动画实际速度为Speed与Multiplier的乘积(设置Parameter后,可通过脚本修改参数)
  4. Motion Time:播放动画的时间点(注意:只会播放单帧)【适合制作单帧2D动画】
  5. Mirror:镜像动画
  6. Cycle Offset:动画播放的起始位置[0,1]
  7. Foot IK:使用了IK的动画矫正机制
  8. Write Defaults :默认开启,是否为其运动未动画化的属性写回默认值。但是有很大的坑,一般情况下禁用。
    [Unity] AnimatorStates中的write defaults详解:https://blog.csdn.net/rickshaozhiheng/article/details/77838379

动画状态机----动画转换

点击状态,可看到状态下的所有转化。

  • 如果有勾选Solo的转化,只对勾选Solo的状态转换,
    • 哪个转换的条件先满足,就执行哪个转换。
    • 如果条件同时满足,则执行最上面的转换
  • 如果没有勾选Solo的转换
  • 对勾选了Mute的转换永远不会执行

转换属性的配置面板

  • Has Exit Time : 当前动画状态播放到某个时间点的时候,就执行这个转换。如果不勾选,就必须在Conditions下对转换添加其他条件。
  • 展示图
    在这里插入图片描述
    • 最上方的白线:Root motion动画在水平方向上的位移
  • Exit Time:动画开始转化的时间(勾选Has Exit Time下有效)
  • Fixed Duration : 转换的持续时间
    • 勾选(按秒读),后面有(s)
    • 不勾选(按百分比读),后面有(%)
  • Transition Offset:进入下一个动画片段时下一个动画开始播放的偏移量,取值[0,1]。
  • Interruption Source : 表示哪些转化可以打断当前这个转换
    • None:当前这个状态不可被打断
    • Current State:可以被当前出发状态的其他转换打断
    • Next State:可被从目的状态出发的其他转换打断
    • Current State Then Next State:出发状态的其他状态优先
    • Next State Then Current State:目的状态的其他状态优先
  • Ordered Interruption:默认被勾选,只有优先集比当前转换的优先级高的转换才可打断当前转换(点击状态,状态转化栏中,越靠上的优先级越高)。不勾选的话,则不考虑优先级。
  • Conditions
    • 使用setTrigger,setInt等激活触发器或来改变条件的值设置值
    • 如果与Trigger相关联的动画并没有被执行,trigger就会一直处于激活状态,直到转换被执行。
    • 转换条件可以设计多条,之间的关系为逻辑与(当所有条件都满足时才会转换)

、、、、

  • Layers 用于组合动画
    越向下,优先级越高
  • Parameters
//修改参数值
animator.SetFloat("参数名称",);
animator.SetBool("参数名称",);
//内部会自动转为Hash值,及如下方法
animator.SetFloat(Animator.StringToHash("参数名称"),);
//获取参数值
animator.getInt("参数名称");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/730308.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

selenium 02

✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录 等待浏览器的操作键盘事件鼠标事件定位一组元素多层框架定位下拉框处理弹窗处理上传文件操作关闭浏览器切换窗口截图 等待 s…

SOLIDWORKS小问题解答 硕迪科技

众所周知,SOLIDWORKS的使用者非常多,在使用过程中呢也会有一些小问题,前几天就有朋友来咨询了两个问题,可能其他使用者也有这样的问题,所以今天硕迪科技统一为大家解答 问题一:SOLIDWORKS装配图中的颜色怎么…

csv文件如何在单元格内保留换行 \r\n

csv文件如何在单元格内保留换行 \r\n 一、问题描述 我们都知道 csv 文件内是通过 , 来切分单元格的。 但如果某个单元格内的内容有换行: 34, KyleBing, 你好 # 这里换行了 我的名字是 kyebing 35, Tina, hello 36, Lucy, nice to meet you当用 Excel 打开的时候…

如何使Revit导出带有标准材质的FBX模型?

如何使Revit导出带有标准材质的FBX模型? 初次使用Revit导出fbx格式模型,在导出模型后发现模型材质丢失了,上网查询之后也没到具体原因是什么,不过倒是找到了解决方式:在Revit中安装naviswork插件,然后从re…

Vue之router和vuex

Vue之router和vuex 在学习之前,我们可以先安装一个插件,是一个浏览器插件,这个插件的作用是可以让我们更好的观察到数据的变化和状态的变更 他是一个github的链接,如果你没办法科学上网的话,也可以在 插件下载 上面这…

CodeQL在代码审计中的应用

一、CodeQL简介 CodeQL是一种基于静态分析的程序分析工具,由GitHub开发和维护。截止到此刻,CodeQL在Github上已经有超过6100个Star。它可以用于发现代码中的漏洞、代码质量问题和安全问题。CodeQL使用了一种特殊的编程语言QL(查询语言&#…

【Unity项目】Unity实现 双屏显示效果

需求:两个屏显示项目,一个屏显示列表,一个屏显示列表按钮点击后的效果。 最近在修改一个项目,是要求分屏显示项目,一个一体机,一个大屏,一体机当作目录界面,大屏当作模型显示界面&am…

NC140 排序

冒泡排序 public int[] BubbleSort(int[] arr) {// write code herefor (int i 0; i < arr.length - 1; i) {for (int j 0; j < arr.length - 1 - i; j) {if (arr[j] > arr[j 1]) {int temp arr[j];arr[j] arr[j 1];arr[j 1] temp;}}}return arr;}插入排序 p…

HTTP1.0、HTTP1.1、HTTP2.0、HTTP3.0的关系和区别

文章目录 一、对比二、HTTP1.0三、HTTP1.1四、HTTP2.0四、HTTP/3.0五、总结 一、对比 二、HTTP1.0 浏览器的每次请求都需要与服务器建立一个TCP连接&#xff0c;服务器处理完成后立即断开TCP连接&#xff08;无连接&#xff09;&#xff0c;服务器不跟踪每个客户端也不记录过去…

如何使用js对图像进行压缩

JavaScript 可以使用类似于 canvas 和 web workers 来实现图像压缩。 使用 canvas&#xff0c;可以将图像绘制到 canvas 上&#xff0c;然后使用 canvas 提供的 toBlob() 或 toDataURL() 方法将其转换为不同格式的图像。在这些方法中指定图像质量参数即可实现压缩。 使用 web…

python接口自动化(二十)--token登录(详解)

简介 为了验证用户登录情况以及减轻服务器的压力&#xff0c;减少频繁的查询数据库&#xff0c;使服务器更加健壮。有些登录不是用 cookie 来验证的&#xff0c;是用 token 参数来判断是否登录。token 传参有两种一种是放在请求头里&#xff0c;本质上是跟 cookie 是一样的&…

【JS】自调用函数(自执行函数)

文章目录 自调用函数&#xff1a;只能自己在定义的同时调用自己一次&#xff0c;对外界不可见。 语法 // 函数名加与不加都可以 (function 函数名(形参){console.log(11); })(实参)使用&#xff1a; // 用法一 const str 流星; (function (params){console.log(params); // …

33.RocketMQ之Broker启动源码

highlight: arduino-light Broker启动流程:BrokerStartup#main java public static void main(String[] args) { //手动指定了 nameServer start(createBrokerController(args)); } java public static BrokerController start(BrokerController controller)…

Docker开启远程端口访问2375

开启方法&#xff1a; 1、修改/etc/default/docker下的配置 cat >> /etc/default/docker <<EOF DOCKER_OPTS"-H tcp://0.0.0.0:2375" EOF systemctl restart docker 2、修改/usr/lib/systemd/system/docker.service配置 cat >> /usr/lib/systemd/s…

第四章 网络层【计算机网络】

第四章 网络层【计算机网络】 前言推荐第四章 网络层4.1 网络层的几个重要概念4.1.1 网络层提供的两种服务4.1.2 网络层的两个层面 4.2网际协议IP4.2.1 虚拟互连网络4.2.2 IP地址4.2.3IP地址与硬件地址4.2.4地址解析协议ARP4.2.5IP数据报的格式 4.3 IP层转发分组的过程4.3.1 基…

个人域名邮箱无法给gmail发邮件

问题描述 我注册了一个域名 mydomain.com, 并在此域名下创建了 mailbox&#xff0c;从该邮箱向外发送邮件和接收邮件会失败。 主要是一些配置工作没有做好。 接收邮件 当创建邮箱 xxxmydomain.com&#xff0c;尝试向该邮箱发送邮件时&#xff0c;邮件会被拒收&#xff0c;并…

选择正确的负载均衡器:LVS还是Nginx?

选择正确的负载均衡器&#xff1a;LVS还是Nginx&#xff1f; 博主简介一、前言二、什么是LVS&#xff1f;2.1、LVS的架构 三、什么是Nginx&#xff1f;3.1、Nginx 特性3.2、Nginx 架构 四、LVS和Nginx的区别五、总结 博主简介 &#x1f4a1;一个热爱分享高性能服务器后台开发知…

windows环境下根据端口号查询进程编号并杀掉此进程

说在前面 当端口号备占用时&#xff0c;我们需要找到占用端口的进程&#xff0c;然后杀掉该进程&#xff0c;即可 开干 1、找占用端口的进程&#xff0c;比如现在是3306端口备占用了 netstat -nao|findstr 3306运行如下&#xff1a; 2、杀掉进程&#xff0c;比如进程号为…

【InnoDB 存储引擎】15.4 InnoDB Architecture

文章目录 1 InnoDB 存储引擎结构2 参考资料 1 InnoDB 存储引擎结构 下面的图显示了内存和磁盘结构组成InnoDB存储引擎架构 内存结构&#xff1a;Section 15.5, “InnoDB In-Memory Structures” Buffer Pool&#xff08;缓冲池&#xff09;Change Buffer&#xff08;修改缓冲&…

JavaScript笔记——快速了解 ES6 新增字符串方法,开箱即用(含案例)

文章目录 &#x1f4cb;前言&#x1f3af;includes() 方法&#x1f3af;startsWith() 方法&#x1f3af;endsWith() 方法&#x1f3af;repeat() 方法&#x1f3af;padStart() 方法&#x1f3af;padEnd() 方法&#x1f3af;trim() 方法&#x1f3af;trimStart() 或 trimLeft() 方…