Unity学习笔记——核心(叁)
学习笔记主要来源于唐老狮的Unity课程,经过个人简单整理而成。目前笔记可能有些地方写的不够好,若发现问题后续会继续完善。笔记总共三个部分:
四、核心知识
1、图片纹理Texture
(1)Unity支持的图片格式
- BMP:Windows 系统标准图像格式,几乎无压缩,磁盘占用大。
- TIF:基本不损失图像信息,缺点是体积大。
- JPG(JPEG):有损压缩格式,文件体积小,但会损失部分图像数据,无透明通道。
- PNG:无损压缩位图格式,压缩比高、文件体积小,支持透明通道。
- TGA:支持不失真压缩,体积小、效果清晰,兼具 BMP 的质量与 JPG 的体积优势,支持透明通道。
- PSD:Photoshop 专用格式。
- 其他支持格式:
EXR、GIF、HDR、IFF、PICT等。
Unity 开发中最常用的图片格式是 JPG、PNG、TGA 三种。
(2)MipMap
MipMap是三维图形渲染中的一种纹理优化技术,也叫多级纹理映射。Unity 会为原始贴图生成一系列不同分辨率的缩小副本,组成一个纹理链。
MipMap可以提升渲染效率,物体距离摄像机越远,Unity 会自动使用更低分辨率的 MipMap 层级,而且MipMap图片预先做过抗锯齿处理,减少实时渲染的负担。缺点就是会占用额外的内存空间。
MipMap中,每个层级的图片都是上一层级的 1/4 大小(宽高各缩小一半)。比如一张 256×256 的贴图,MipMap层级依次为:128×128、64×64、32×32、16×16、8×8、4×4、2×2、1×1。
(3)Texture参数
Texture Type:纹理类型Texture Shape:纹理形状2D:最常用的设置,适用于模型贴图、UI、Sprite 等绝大多数场景。Cube:立方体贴图,主要用于天空盒和反射探针。Mapping:纹理投影方式Convolution Type:纹理过滤类型
Advanced:高级设置Non-Power of 2:非 2 的幂次尺寸处理方式Read/Write:是否允许通过脚本读取 / 修改纹理数据。Generate Mip Maps:是否生成多级纹理(MipMap)。
Wrap Mode:纹理平铺 / 包裹方式Filter Mode:纹理过滤模式Aniso Level:各向异性过滤,以大角度查看纹理时提升清晰度,性能消耗较高。Max Size:纹理导入的最大尺寸限制,超过则自动缩小。Resize Algorithm:纹理缩小算法Format:纹理压缩格式,不同平台支持不同格式,可自动适配或手动设置。Compression:压缩质量Use Crunch Compression:启用 Crunch 有损压缩,解压速度快,适合移动端。
2、精灵图Sprite
(1)Sprite Editor
Sprite Editor是精灵图片编辑器,需要安装 2D Sprite 包才可以编辑。
编辑界面有4个功能:
- Sprite Editor 基础设置:设置精灵图片的基础属性以及对图集进行切割。
- Custom Outline 自定义轮廓:自定义精灵网格的轮廓形状,控制渲染区域。
- Custom Physics Shape 自定义物理形状:决定碰撞区域。
- Secondary Textures 次要纹理:添加特殊效果。
(2)Sprite Renderer
Sprite Renderer是用于场景中渲染精灵图片的组件。
Sprite:指定渲染的精灵图片。Color:精灵的着色颜色。Flip:水平 / 竖直翻转精灵图片。Draw Mode:绘制模式,尺寸变化时的缩放方式。Mask Interaction:与精灵遮罩的交互方式。Sprite Sort Point:相机计算距离时使用的参考点(Center或Pivot)。Material:精灵使用的材质,默认不受光照影响;如需受光照影响,可选择Default-Diffuse。Sorting Layer:渲染排序图层,控制精灵的层级优先级。Order in Layer:同图层内的渲染顺序,数值越大越靠上显示。
(3)Sprite Creator
Unity 自带的精灵创建工具,用于生成基础几何形状的精灵图片,作为 2D 游戏的临时替代资源。在 Project 窗口右键创建,可生成圆形、矩形、多边形等形状的精灵。
(4)Sprite Mask
精灵遮罩用于对精灵图片产生遮罩效果,实现只显示图片局部区域的功能。
Sprite:用作遮罩的图片,白色区域可见,黑色区域透明。Alpha Cutoff:半透明区域的分界点,控制遮罩边缘的过渡效果。Custom Range:开启后可自定义遮罩的生效范围,按排序层划分。Sprite Sort Point:计算遮罩生效时使用的参考点(Center 或 Pivot)。
(5)Sorting Group
用于对多个精灵进行分组排序,组内精灵会作为整体参与渲染顺序计算。
Sorting Layer:分组的排序图层。Order in Layer:分组在图层内的渲染顺序,数值越大越靠前。Sort At Root:是否以根对象为基准进行排序。
(6)Sprite Atlas
Sprite Atlas用于将多张精灵图片打包成一张大图集,减少 Draw Call,提升渲染性能。
在Edit → Project Setting → Editor → Sprite Packer中可以选择图集功能的开启和关闭。
图集关键属性如下:
-
Type:图集类型- Master:主图集
Include in Build:勾选后,图集资源会被打包进游戏构建包中。Allow Rotation:打包时允许旋转精灵,提升图集打包密度。UI 图集请禁用此选项,否则会出现旋转错位。Tight Packing:启用后,会根据精灵的实际轮廓进行打包,提升密度。Padding:设置图集中各精灵之间的间隔像素,防止渲染时出现颜色溢出。
- Variant:变体图集
Master Atlas:关联的主图集。Scale:变体图集的缩放因子。
- Master:主图集
-
Read/Write:允许脚本访问纹理数据。 -
Generate Mip Maps:是否生成多级纹理(MipMap)。 -
sRGB:是否将纹理存储在伽马空间。 -
Filter Mode:纹理拉伸 / 缩放时的过滤方式 -
Objects for Packing:关联需要打包的精灵,注意:必须是设置为Sprite类型的图片。
图集中精灵图的获取:
atlas.GetSprite(name);
(7)SpriteShape
SpriteShape 用于快速制作 2D 游戏地形 / 背景的工具。需在 Package Manager 中导入 SpriteShape包。
- Sprite Shape Profile:精灵形状配置文件,用于定义地形各部分使用的精灵资源。
- SpriteShapeRenderer:精灵形状渲染器,控制 SpriteShape 的渲染属性。
- SpriteShapeController:精灵形状控制器,控制地形的路径和生成规则。
(8)换装
Unity 2D 换装可以使用Sprite Library和Sprite Resolver实现。
Sprite Library:精灵资料库组件,挂在角色根物体上,关联Sprite Library Asset文件,管理所有换装资源的类别分组信息。Sprite Resolver:精灵解算器组件,挂在角色的各个部位(如头部、身体、武器)上,用于确定该部位的类别和当前使用的图片。
3、Tilemap
Tilemap 瓦片地图用于快速编辑2D游戏的场景。需在Package Manager中导入2D Tilemap Editor包。
(1)创建Tilemap
Hierarchy窗口中,右键选择2D Object/Tilemap即可创建Tilemap。
(2)创建TilePalette
Tilemap相当于一张纸,我们需要颜料才能开始画画,首先需要TilePalette调色板。
Window/2D/Tile Palette可以打开调色盘窗口,Project窗口右键选择2D/Tile Palette可以创建调色盘(或是在调色盘窗口创建)。
(3)创建Tile
Tile就是瓦片,即调色盘中的颜料。将图片资源拖入调色盘,即可创建瓦片。
(4)工具栏
- 选择工具(S):选择瓦片。
- 移动工具(M):移动选中的瓦片区域。
- 画笔工具(B):单个绘制瓦片,选取后自动切换。
- 框填工具(U):范围填充瓦片。
- 选取器工具(I):拾取地图上的瓦片作为样本。
- 橡皮擦工具(D):擦除瓦片。
- 填充工具(G):批量填充连续区域。
(5)特殊瓦片
- Rule Tile:规则瓦片,根据相邻瓦片的存在规则自动切换精灵,实现地形边缘的自然过渡。
- Animated Tile:动画瓦片,由序列帧组成,可播放循环动画。
- Pipeline Tile:管道瓦片,根据相邻瓦片的数量自动切换精灵,用于制作管道、电线等连接图形。
- Random Tile:随机瓦片,从预设的多个精灵中随机选择绘制。
- Terrain Tile:地形瓦片, Rule Tile 的扩展,用于制作自然地形的边缘过渡,根据相邻瓦片的不同组合自动切换精灵。
(6)笔刷
- Coordinate Brush(坐标笔刷):实时显示格子坐标,便于定位和调试。
- GameObject Brush(游戏对象笔刷):直接在瓦片地图上放置游戏对象(如道具、敌人),仅作用于选定父对象的子级。
- Group Brush(组合笔刷):可设置范围参数,点击单个瓦片时自动绘制预设范围内的一组瓦片。
- Line Brush(线性笔刷):通过指定起点和终点,自动绘制一条连续的瓦片线。
- Random Brush(随机笔刷):从预设的瓦片列表中随机选择绘制,增加地图的自然随机性。
(5)Grid组件
Grid 组件是用于提供网格坐标规则的基准引导组件,专门用来规范瓦片、格子类布局的 GameObject 对齐规则。
Cell Size:单元格的尺寸。Cell Gap:单元格之间的间隔大小。Cell Layout:网格排列方式。Cell Swizzle:重新映射 XYZ 坐标,适配不同布局。
(6)Tilemap组件
瓦片地图组件,用于存储和处理瓦片资源。
Animation Frame Rate:瓦片动画的播放速率。Color:瓦片的整体色调。Tile Anchor:瓦片的锚点偏移。Orientation:瓦片在 3D 空间中的轴方向。
(7)Tilemap Renderer组件
该组件用于渲染瓦片地图。
Sort Order:瓦片排序方向。Mode:渲染模式。Detect Chunk Culling Bounds:检测瓦片地图的可见边界的方式。Mask Interaction:与精灵遮罩的交互方式。Sorting Layer/Order in Layer:渲染层级与顺序。
(8)代码控制
- 类对象
Tilemap tilemap; // 管理瓦片地图的核心组件
Grid grid; // 处理坐标转换的Grid组件
TileBase tileBase; // 瓦片资源基类,可引用Tile、RuleTile等所有瓦片类型
- Tilemap
tilemap.ClearAllTiles(); // 清除所有瓦片
tilemap.GetTile(pos); // 获取指定格子的瓦片
tilemap.SetTile(pos, tile); // 设置瓦片(tile为null表示删除瓦片)
tilemap.SwapTile(changeTile, newTile); // 替换所有changeTile为newTile
- Grid
grid.CellToWorld(cellPos); // 将网格坐标转换为世界坐标
grid.WorldToCell(worldPos); // 将世界坐标转换为网格坐标
(9)网格坐标
在Tilemap中,我们会用到新的坐标,即网格坐标,类型为Vector3Int,以单元格为单位进行计算。
4、初识动画系统
(1)Animation 窗口
在Window/Animation/Animation可以打开动画窗口,可以为场景中的任意游戏对象制作动画,包括物体位置、旋转、缩放、组件参数的变化等等。
(2)Animation Clip动画切片
通过Animation 窗口可以创建动画切片文件Animation Clip。
Loop Time:是否循环播放动画,结束后自动回到开头。Loop Pose:开启后动画首尾帧会自动融合,实现无缝循环效果。Cycle Offset:循环动画的周期偏移,控制动画从不同时间点开始播放。
(3)老动画系统Animation
Unity 早期动画系统,现在基本不再使用,新项目推荐使用动画状态机Animator。
-
Animation组件
Animation:默认自动播放的动画片段。Animations:控制的所有动画片段列表。Play Automatically:是否在游戏启动时自动播放默认动画。Animate Physics:动画是否与物理引擎交互。Culling Type:动画剔除模式。
-
Animation Clip动画切片
在Animation组件中,动画切片属性有所变化,只有一个属性Wrap Mode,控制动画播放结束后的行为。
- 代码控制
animation.Play(animation); // 播放动画
animation.CrossFade(animation); // 淡入播放
animation.CrossFadeQueued(animation); // 队列播放
animation.Stop(); // 停止播放
animation.IsPlaying(animation); // 是否正在播放
(4)Animator动画状态机
Animator是 Unity 实现有限状态机的核心工具,专门用于管理角色动画的状态切换。
为对象创建动画时,Unity 会自动生成Animator Controller;或者 Project 窗口右键Create → Animator Controller。
-
Animator组件
Controller:对应的动画控制器。Avatar:对应替身配置信息(3D模型会讲解)。Apply Root Motion:选择从动画本身还是从脚本控制角色的位置和旋转,勾选则表明是动画本身。Update Mode:更新模式,表明 Animator 何时更新。Culling Mode:裁剪剔除模式。
-
Animator窗口:在
Window/Animation/Animator可以打开动画状态机窗口。这里介绍几个常用的。Layers:动画层级,层级高的动画会覆盖层级低的动画。Parameters:状态切换的参数,总共四种参数。- 矩形节点:代表一个动画状态。
- 箭头连线:代表动画状态间的过渡关系,可设置切换条件。若有多个条件,需同时满足才会切换。
-
代码控制
animator.SetFloat(name, value); // 设置 Float 类型参数
animator.GetFloat(name); // 获取 Float 类型参数
animator.SetInteger(name, value); // 设置 Int 类型参数
animator.GetInteger(name); // 获取 Int 类型参数
animator.SetBool(name, value); // 设置 Bool 类型参数
animator.GetBool(name); // 获取 Bool 类型参数
animator.SetTrigger(name); // 触发 Trigger 类型参数(如一次性事件)
animator.Play(name); // 直接播放对应动画
(5)2D序列帧动画
序列帧动画的本质是以固定时间间隔按序列切换图片,利用人眼的视觉暂留效应,让静态图片看起来是连续动态的。
将某一动作的序列帧图片直接拖入 Animation 窗口中,Unity 会自动生成关键帧。
(6)2D骨骼动画
骨骼动画利用 3D 骨骼动画的原理,将一张 2D 图片分割成多个部位,为每个部位绑定骨骼,通过控制骨骼的移动、旋转来驱动图片变形,实现流畅的动画效果。
可以使用 Unity 的 2D Animation 来制作(需导入2D Animation包),或是使用跨平台骨骼动画工具 Spine 制作。
(7)IK反向动力学
反向动力学(Inverse Kinematics)是 2D 骨骼动画的高级功能,它可以通过控制骨骼末端的位置,自动反向计算出整个骨骼链的姿态,实现更自然的动作效果。
- 正向动力学(FK):父骨骼的旋转带动子骨骼运动,比如抬起肩膀时,整个手臂跟着运动,父关节驱动子关节。
- 反向动力学(IK):骨骼末端(子)的位置变化,反向带动父骨骼旋转。比如手去拿杯子时,杯子的位置决定了手臂的整体姿态,目标位置驱动整个骨骼链。
Unity 内置了IK,需要导入2D IK工具包(Unity 2021+ 已集成在 2D Animation 中)。
5、模型制作流程
- 建模:利用三角面片拼接搭建物体基础外形,生成模型网格几何数据。一般全部使用三角面,保证引擎兼容性。
- 展UV:将三维模型表面展开为二维平面,建立UV坐标映射关系,为贴图绘制做准备。
- 材质贴图:通过纹理贴图赋予模型色彩、细节;配合着色器Shader生成材质,模拟金属、玻璃等物理质感。
- 骨骼绑定:给模型搭建骨架,并将网格顶点绑定到骨骼,让骨骼可以带动模型形变,为动画打下基础。
- 动画制作:在时间轴设置骨骼关键帧,软件自动补全过渡帧,制作走路、攻击等动态动作。
6、Unity 3D模型
(1)模型概述
Unity 原生支持多种模型格式,比如fbx、dae、3ds、dxf、obj等。常用的为FBX格式。导入模型后,会在Inspector窗口看到如下4个页签:
- Model:模型页签,主要设置模型的基础属性。
- Rig:骨骼页签,用于配置模型的骨骼与动画系统。
- Animation:动画页签,设置模型包含的动画片段。
- Materials:材质纹理页签,管理模型的材质与纹理。
(2)Model页签
Scene 场景相关设置:
Scale Factor:模型全局缩放比例。Convert Units:启用后将建模软件的单位转换为 Unity 单位。Import BlendShapes:是否导入混合形状,启用后模型会使用Skinned Mesh Renderer组件。Import Visibility:是否导入模型的可见性,启用后可以从FBX文件读取可见性属性。Import Cameras:是否导入模型中的摄像机。Import Lights:是否导入模型中的光源。Preserve Hierarchy: 始终创建一个显式预制件根,保留模型的层级结构,防止 Unity 自动优化空节点导致动画不匹配,常用于骨骼与动画分离的 FBX 文件。Sort Hierarchy By Name:是否按名称排序层级子物体,不启用则保留 FBX 文件中的原始层级顺序。
Meshes 网格相关设置:
Mesh Compression:通过压缩网格数据减小文件大小,可以选择压缩等级。Read/Write:开启后 CPU 会保留网格数据副本,可通过代码修改网格,会增加内存占用。。Optimize Mesh:优化网格顶点和三角形顺序,提升 GPU 性能,可以选择优化方式。Generate Colliders:自动为模型生成网格碰撞器,适合静态环境几何体,动态物体建议手动添加碰撞器。
Geometry 集合相关设置:
Keep Quads:是否保留四边形面,不自动转换为三角形,使用曲面细分着色器时可提升效率。Weld Vertices:是否合并空间位置和属性相同的顶点,减少网格顶点数量。Index Format:网格索引缓冲区大小,默认16 bits即可满足需求。Legacy Blend Shape Normals:启用此选项可基于 Smoothing Angle 值来计算法线。Normals:法线导入方式。Normals Mode:法线计算权重模式Smoothing Angle:控制硬边拆分顶点的阈值,值越大顶点越少,建议在建模软件中手动平滑处理。Tangents:顶点切线导入 / 计算方式。Swap UVs:是否交换 UV 通道,如漫反射和光照贴图 UV。Generate Lightmap UVs:自动生成光照贴图用的第二套 UV。
(3)Rig页签
总共四种动画类型:
None:静态环境模型无动画需求,不导入骨骼信息。Humanoid:标准人形角色,支持 Avatar 系统,可实现动画重定向,不同角色之间的动作复用。Generic:通用模型(如怪物、载具),需手动设置根骨骼。Legacy:旧版 Unity 动画,兼容 Unity 3.x 及更早版本,一般不推荐使用。
Humanoid 人形模型:
Avatar Definition:选择获取Avatar定义的位置。Skin Weights:皮肤权重,设置影响单个顶点的最大骨骼数量。Optimize Game Objects:优化游戏对象,在 Avatar 和 Animator 组件中删除和存储所导入角色的游戏对象骨骼层级信息,启用后会显示Extra Transforms to Expose选项,设置需要公开的骨骼层级。
Generic 通用模型:
Root Node:指定模型的根骨骼,作为动画的层级起点。
(4)Avatar化身系统
Avatar 化身系统通过标准化骨骼映射实现动画的跨角色复用。简单来说,人的整体结构都是一致的,而化身系统的本质就是动作的模仿,我们可以把标准人形动作通过化身系统复用到其他人形模型上,只需保证关节点对应关系是一致的。
Rig页签的人形模型的Avatar Definition中选择Create From This Model,之后即可点击Configure进行关节映射设置。
- Mapping页签:用于模型关节的映射设置,确保动画重定向时动作能正确映射。
- Muscles & Settings页签:用于设置骨骼的运动范围和动画行为。
Muscle Group Preview:肌肉群预览,通过滑块预览骨骼在不同动作下的旋转效果,验证关节映射是否合理。Per-Muscle Settings:单骨骼设置,为每个骨骼设置旋转角度的上下限,防止动画中骨骼超出合理范围导致模型变形。Additional Settings:高级设置Upper/Lower Arm/Leg Twist:设置肢体的扭转角度,优化手臂、腿部旋转时的自然度。Arm/Leg Stretch:设置肢体的拉伸系数,控制动画中肢体的伸缩幅度。Translation DoF:是否启用骨骼位移动画,启用则使用人形角色的移动动画,禁用则仅使用旋转对骨骼进行动画化。一般当动画包含骨骼位移(如移动、跳跃)时启用。
(5)Animation页签
基础信息:
Import Constraints:从此资源导入约束,启用后 Unity 会自动添加约束组件并关联到对应对象。Import Animation:从此资源导入动画,不勾选则无法导入任何动画。Bake Animations:通过反向动力学或模拟创建的动画以便推进运动关键帧,适用于 Maya、3ds Max 等软件导出的文件。Anim. Compression:导入动画的压缩类型。Rotation/Position/Scale Error:设置旋转、位置、缩放曲线的压缩容错精度,原始值与削减值的差小于原始值乘以容错百分比时,会删除关键帧。Clips:动画剪辑选择列表。
动画剪辑信息:
Loop Time:是否循环播放动画。Loop Pose:实现无缝循环,配合Loop Match(循环匹配)验证效果。Cycle Offset:循环动画在其他时间开始时的周期偏移。
Root Transform Rotation:控制根节点的旋转处理,可选择基于原始旋转、根节点旋转或身体朝向。Root Transform Position (Y):控制根节点的垂直位置处理,可选原始位置、根节点位置、质心对齐或脚部对齐。Root Transform Position (XZ):控制根节点的水平位置处理,可选原始位置、根节点位置或质心对齐。Bake Into Pose:将根运动烘培到骨骼动画中,禁用时才会作为根运动驱动角色位移。Mirror:对动画进行左右镜像。Additive Reference Pose:启用附加动画层的参考姿势的帧,用于制作叠加动画效果,Pose Frame可设置参考帧位置。
其他设置:
Curves:动画曲线用于将自定义数据与动画同步。X 轴表示动画开始到结束的时间;Y 轴则是自定义数值。之后可在代码或状态机中读取曲线值,触发对应逻辑。Event:动画事件允许在动画播放的特定帧触发脚本函数。Mask:动画遮罩用于限制动画影响的骨骼范围,实现上 / 下半身独立动画效果,点击部位图标使其变红,代表该部位不受当前动画影响。Transform可明确哪些骨骼关节不受影响。Motion:当动画剪辑包含根运动时,可在此指定根运动节点。Import Messages:用于排查动画导入问题,启用后会生成更多有关重定向问题的具体信息。
(6)Material页签
Material Creation Mode:决定 Unity 如何为模型生成或导入材质。sRGB Albedo Colors:是否在伽马空间中使用反射率颜色。使用线性颜色空间的项目请禁用。Location:定义如何访问材质和纹理。Use External Materials (Legacy):传统模式。Naming:定义材质命名规则。Search:定义在使用Naming选项定义的名称时,查找现有材质的位置规则。
Use Embedded Materials:将材质嵌入模型文件中。Extract Textures/Materials:提取导入的所有材质和纹理。
7、3D动画
(1)动画状态设置
选中Animator窗口中的状态机状态,可在 Inspector 面板中设置以下参数:
Motion:分配给此状态的动画剪辑。Speed:动画的默认播放速度,配合Multiplier可实现动态变速。Multiplier:速度乘数,可关联 Float 类型参数。Motion Time:动画时间控制,可关联 Float 类型参数。Mirror:人形动画专用,为状态生成镜像动画,可关联 Bool 类型参数。Cycle Offset:循环偏移时间,需关联 Float 类型参数调整动画起始位置。Foot IK:人形动画专用,是否启用脚部 IK。Write Defaults:动画状态结束后,是否将未动画化的属性恢复为默认值。Transitions:动画过渡,勾选Solo则仅播放该状态的过渡;勾选Mute则禁用过渡;两者一起勾选Mute优先生效。Add Behaviour:添加状态机行为脚本,后续会讲解。
(2)状态过渡设置
状态机中的状态间的箭头代表动画过渡,选中箭头后可配置以下参数:
Has Exit Time:是否启用退出时间。勾选后,动画必须播放到指定百分比才会触发过渡;取消勾选可实现瞬间切换。Exit Time:退出时间点(百分比),值大于 1 时会循环多次后过渡。Fixed Duration:启用后,过渡持续时间以秒为单位;禁用则以百分比解读。Transition Duration:过渡持续时间,即两个动画之间的混合时长。Transition Offset:目标状态的起始播放偏移,如 0.5 表示从目标动画的一半位置开始播放。Interruption Source:控制过渡被中断的规则Ordered Interruption:是否按顺序中断过渡,勾选后仅按优先级中断,不打乱过渡队列。
从Any State过渡的话还会有如下参数:
Can Transition To Self:是否允许状态过渡到自身,常用于循环动作的刷新,如受击状态重置。Preview Source State:预览从任意状态切换到当前状态的过渡效果,便于调试过渡表现。
(3)动画分层与遮罩
动画分层可以实现对角色动作的分层,比如角色有健康状态与残血状态的两套动作,通过分层就可以实现不同状态播放不同的动作。
动画分层和遮罩的结合可以实现动作的叠加播放,比如上/下半身动作分开,两者分别播放就可以实现动画的排列组合播放,避免制作过多美术资源。
在Animator窗口的Layers中即可进行层级的设置,有如下几个参数可以设置:
Weight:层权重,控制该层动画对最终效果的影响比例。Mask:绑定动画遮罩,限定该层动画影响的骨骼范围。Blending:混合模式,决定该层动画与其他层的交互方式。Override:覆盖模式,播放该层动画时,忽略其他层的信息。Additive:叠加模式,该层动画与其他层动画叠加播放,根据权重决定叠加比例。
Sync:是否同步其他层,勾选后,可复制其他层的状态机结构。Timing:选中Sync时激活该参数,若勾选则采用这种方案调整同步层上的动画时长(基于权重计算),否则动画时长使用原始层作为模板。IK Pass:反向动力学,后续会讲解。
(4)动画混合树
动画混合树可以在两个或多个相似运动之间进行平滑混合,是高级版的动画过渡。在Animator窗口中右键选择Create State / From New Blend Tree可以创建混合树。
- 1D动画混合树
Parameter:控制混合的参数。Motion:关联的动画剪辑,可通过拖拽调整顺序。Threshold:对应动作的临界阈值,当参数等于该值时,此动画权重最大(完全播放)。Automate Thresholds:自动设置阈值,在参数取值范围内平均分配。Compute Thresholds:自动计算阈值的方式,从动画剪辑的根运动中获取数据。Adjust Time Scale:调整动画时间刻度。
- 2D动画混合树
- 2D Simple Directional:简单定向模式,运动表示不同的方向时使用,如前后左右走路的动画,同一方向只有单一动画。
- 2D Freeform Directional:自由定向模式,运动表示不同的方向时使用,同一方向可包含多个动作(如向前走 / 跑)。
- 2D Freeform Cartesian:自由笛卡尔坐标模式,当混合的2个参数不代表不同的方向时使用,比如角速度和线速度组合(比如向前走不转向、向前走右转、向前走左转)。
- Direct:自由模式,可以自由控制每个节点权重,一般做表情动作等。
(5)子状态机
子状态机是嵌套在主状态机中的独立状态机,用于管理由多个动作组成的复杂状态,比如技能连招,多个动作组合成一个独立的子状态机。
在Animator窗口中右键选择Create Sub-State Machine即可创建子状态机。需要注意的是要正确配置子状态机与外部状态的过渡连接,确保状态切换逻辑清晰。
(6)IK控制
之前已经介绍过了IK,接下来讲下如何代码控制。需要在状态机的分层Layer设置中开启IK Pass。
Unity定义了一个IK的回调函数:OnAnimatorIK,在该函数中调用IK相关API可以控制IK。
private void OnAnimatorIK(int layerIndex)
{
// 头部IK
animator.SetLookAtWeight(weight, bodyWeight, headWeight, eyesWeight); // 设置头部IK权重
animator.SetLookAtPosition(lookAtPosition); // 设置头部IK看向位置
// 四肢IK(右脚为例)
animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, value); // 设置IK位置权重
animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, value); // 设置IK旋转权重
animator.SetIKPosition(AvatarIKGoal.RightFoot, goalPosition); // 设置IK对应位置
animator.SetIKRotation(AvatarIKGoal.RightFoot, goalPosition); // 设置IK对应角度
}
这里再简单介绍下两个生命周期函数:
OnAnimatorIK:为每个启用IK pass的 Animator Controller 层进行一次此调用,在Update之后和LateUpdate前调用。OnAnimatorMove:在每个更新帧中为每个 Animator 组件调用,修改根运动。
(7)动画目标匹配
当角色动作播放完毕后,需要将手 / 脚精准定位到特定位置),可通过MatchTarget实现位移与目标位置的对齐。
animator.MatchTarget(
matchPosition, // 目标位置
matchRotation, // 目标角度
avatarTarget, // 骨骼位置
weightMask, // 位置角度权重
startNormalizedTime, // 开始匹配的动画百分比
targetNormalizedTime // 结束匹配的动画百分比
);
注意:必须确保动画已切换到目标状态,且未处于过渡阶段。需开启Animator组件的Apply Root Motion才能生效。
(8)状态机行为脚本
状态机行为脚本是一类特殊的脚本,继承自StateMachineBehaviour基类,直接关联到动画状态机状态上。它允许你在动画状态的进入、退出、保持等阶段执行逻辑处理。
点击动画状态的Add Behaviour即可为其添加脚本。有如下几个函数:
OnStateEnter:进入状态时,在第一个Update帧中调用。OnStateExit:退出状态时,在最后一个Update帧中调用。OnStateIK:刚好在OnAnimatorIK之后调用。OnStateMove:刚好在OnAnimatorMove之后调用。OnStateUpdate:除第一帧和最后一帧外,每个Update帧中调用。OnStateMachineEnter:进入子状态机时,在第一个Update中调用。OnStateMachineExit:退出子状态机时,在最后一个Update中调用。
(9)状态机复用
在Project窗口右键,点击Create / Animator Override Controller即可创建复用状态机,可以关联一个基础的状态机,此时复用状态机的状态和过渡都是和基础状态机一致的,只需设置不同动画即可。
8、角色控制器
角色控制器Character Controller可以让角色进行受碰撞约束的移动,同时不必处理刚体。如果对角色使用刚体进行判断碰撞,可能会有奇怪的表现,而角色控制器会更加稳定,专门用于控制角色。
添加Character Controller后,不必再添加刚体,可以检测OnCollisionXXX和OnTriggerXXX函数,可以被射线检测。
组件核心参数如下:
Slope Limit:限制角色能攀爬的最大斜坡角度,超过角度无法向上行走。Step Offset:角色可以自动迈上的最大台阶高度。Skin Width:皮肤厚度,两个碰撞体可以彼此穿透的最大皮肤宽度,较大值可以减少抖动,较小值可能会导致角色卡住,建议设置为半径的10%。Min Move Distance:最小移动距离,如果角色试图移动到指定值以下,则完全不会移动。
相关代码:
characterController.isGrounded; // 是否在地上
characterController.SimpleMove(speed); // 受重力作用的移动
characterController.Move(motion); // 不受重力作用的移动
相关生命周期函数:
// 当在执行 Move 时撞到碰撞体时调用
private void OnControllerColliderHit(ControllerColliderHit hit) { }
9、导航寻路系统
Unity 的导航寻路系统基于 A 星算法优化实现,能够让角色自动避开障碍物、选择最优路径移动。使用前需要安装AI Navigation包。需要学习的内容如下:
- 导航网格(NavMesh):生成寻路用的地形数据,标记可通行区域。
- 导航网格寻路组件(NavMesh Agent):根据地形数据计算路径,控制角色移动。
- 导航网格连接组件(Off-Mesh Link):处理地形断层,实现角色在不同平面间的跳跃 / 移动。
- 导航网格动态障碍物组件(NavMesh Obstacle):适配场景中可移动、可销毁的动态障碍物。
(1)导航网格生成窗口
点击Window/AI/Navigation,可以打开导航网格生成窗口。这里以Obsolete老版本为例。
-
Object页签:设置参与寻路烘焙的对象。
Scene Filter:场景过滤器,可选择显示的对象。Navigation Static:标记对象为导航静态,参与烘焙计算。Generate OffMeshLinks:生成网格连接点,用于断层 / 跳跃场景。Navigation Area:设置对象的导航区域类型,配合 Areas 页签使用。
-
Bake 页签:导航数据烘焙设置,控制网格精度与通行规则。
Agent Radius:代理半径,决定烘焙边缘精度,控制可通行区域范围。Agent Height:代理高度,决定烘焙高度精度,控制拱桥、低矮通道是否可穿越。Max Slope:最大坡度,设置角色可攀爬的斜坡角度。Step Height:台阶高度,设置角色可自动迈上的台阶高度。Generated Off Mesh Links:生成非网格连接,设置断层间的掉落 / 跳跃参数。Drop Height:掉落高度Jump Distance:跳跃间距
Advanced:高级设置Manual Voxel Size:手动设置立体像素大小,控制烘焙精度,减半会使内存和构建时间增加 4 倍,一般无需修改。Min Region Area:最小区域面积,面积小于该值的导航网格会被移除,避免小碎块干扰寻路。Height Mesh:高度网格构建开关,优化斜坡、楼梯等斜面的寻路精度,开启会增加烘焙时间。
-
Areas 页签:导航区域设置,定义不同区域的寻路消耗(Cost)。
- 内置区域:Walkable(可通行)、Not Walkable(不可通行)、Jump(跳跃区域)等。
- 自定义区域:可新增自定的区域,设置不同的寻路消耗,实现角色对不同地形的路径偏好。
-
Agents 页签:寻路代理信息设置,配置代理的基础参数(半径、高度、台阶高度、最大坡度),用于匹配 Bake 页签的烘焙规则。
(2)NavMesh Agent导航网格寻路组件
用于根据烘焙好的导航网格数据,通过 A 星算法计算角色的行进路径,控制角色沿路径移动。
Agent Type:代理类型,配合 Agents 页签的配置使用。Base Offset:基础偏移值,调整角色模型与寻路代理中心点的高度偏移。Speed:角色寻路时的最大移动速度。Angular Speed:角色转向的最大旋转速度。Acceleration:角色的最大加速度。Stopping Distance:角色到达目标点时的停止距离,当与目标距离小于该值时停止移动。Auto Braking:自动制动,到达目标时自动减速,如果是连续移动的,比如巡逻移动建议关闭。Radius:碰撞半径,用于计算角色与障碍物的碰撞范围。Height:碰撞高度,用于计算角色与顶部障碍物的高度间隙。Quality:避障品质,越高避障越精准,但性能消耗越大,无动态障碍物时可设为 None。Priority:避障优先级(0~99),数字越小优先级越高,优先级低的角色会主动避让优先级高的角色。Auto Traverse Off Mesh Link:是否自动遍历网格外的 Off-Mesh Link 连接,自定义逻辑时可关闭。Auto Repath:自动重设路线,当路径被阻断时重新寻路,找到最近的可达点。Area Mask:寻路时考虑的区域类型,可取消勾选某些区域,让角色避开特定地形(如水域)。
代码控制:
// 寻路
navMeshAgent.destination; // 目标点
navMeshAgent.SetDestination(targetPos); // 让角色自动向目标点移动,自动计算路径
navMeshAgent.isStopped; // 是否让角色停止移动
navMeshAgent.updatePosition; // 是否让NavMeshAgent自动更新角色位置
navMeshAgent.updateRotation; // 是否让NavMeshAgent自动更新角色旋转
// 基础属性
navMeshAgent.speed; // 最大速度
navMeshAgent.velocity; // 当前移动速度
navMeshAgent.acceleration; // 加速度
navMeshAgent.angularSpeed; // 转向速度
// 路径
navMeshAgent.hasPath; // 当前是否有路径
navMeshAgent.pathPending; // 路径是否正在计算中
navMeshAgent.pathStatus; // 路径状态
navMeshAgent.path; // 获取路径
navMeshAgent.CalculatePath(targetPos, path); // 计算路径并存储到path中,计算成功则返回True
navMeshAgent.SetPath(path); // 设置路径,成功则返回True
navMeshAgent.ResetPath(); // 清除当前路径
navMeshAgent.Warp(pos); // 瞬间移动到指定位置
(3)Off Mesh Link导航网格外连接组件
该组件用于解决地形断层跳转的问题。在Object页签勾选了Generate OffMeshLinks并且在Bake页签设置了Jump Distance再烘焙就可以自动生成一系列跳跃点。
但若希望两个未连接的平面间,只有指定的有限条连接路径可以跳跃,并且运行时可以动态添加,就可以使用该组件。组件可以添加到任意物体上,参数如下:
Start:起始点。End:终点Cost Override:自定义连接点的寻路消耗值,用于控制路径优先级。如果是负数或 0,则使用Area设置的默认寻路消耗。Bi Directional:是否开启双向连接。开启后角色可从 Start 到 End,也可反向移动。Activated:是否启用该连接点。关闭后寻路时会忽略该连接,路径失效。Auto Update Positions:是否自动更新端点位置。开启后,当起点 / 终点位置变化时,导航网格会同步更新;关闭时,即使位置改变,也会按初始位置计算路径。Navigation Area:设置连接点所属的导航区域。
(4)NavMesh Obstacle导航网格动态障碍组件
用于处理场景中会阻挡角色移动的动态物体。对需要动态阻挡的对象添加该组件,参数如下:
Shape:障碍物的碰撞形状。Center / Size:调整碰撞体的中心位置和大小。Carve:雕刻功能开关,开启后会在导航网格中 “挖洞”,即标记该区域为不可通行。如果动态障碍物是固定不动的建议开启,如门。如果是频繁移动的建议关闭,比如汽车。Move Threshold:移动阈值。当障碍物移动距离超过该值时,会被判定为移动状态,并更新导航网格中的 “孔洞” 位置。Time To Stationary:静止判定时间。当障碍物静止时间超过该值,会被视为真正静止,重新更新导航网格。Carve Only Stationary:仅静止时雕刻。开启后,只有当障碍物处于静止状态时,才会在导航网格中挖洞,移动时则不会更新。