ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

05.Unity游戏开发初学者的第一个练手Demo——动画音效与中文适配

2026/8/11 12:02:18 拓冰建站 浏览量
05.Unity游戏开发初学者的第一个练手Demo——动画音效与中文适配 动画、音效与中文适配给游戏注入生命力Echo Orb 2D 俯视角动作解谜游戏 开发日志第 5 篇作者青竹丹枫 | 南京邮电大学 数字媒体技术 | 2026年8月Tips这是本系列的第五篇正式技术日志啦。前面的四篇写完了核心机制、敌人 AI、UI 系统和地形设计现在我们的Echo Orb 还差一口气这次我们加上了动画和音效那个白色的圆点开始走动的时候会摆腿、那颗子弹打到墙上会叮的一声。这一篇讲的不是最核心的技术但它们是让玩家觉得这东西是用心做了的关键。博主这几天天气原因拖更了呜呜。一、引子动画和音效为什么容易被放到最后我相信很多初学者和我一样在开发早期会把全部精力放在让东西动起来、让敌人会打人、让关卡能切换上。动画和音效永远是排期表上的最后一项因为直觉上它们不是核心功能没有它们游戏也能跑。但事实是当你把一段走路动画和一个走路音效加上去之后整个游戏的完成度感觉至少翻了一倍。一个没有动画的游戏即便逻辑再完整手感也是飘的。一个没有音效的游戏即便画面再好看整个世界也是安静的。这两种东西合在一起才是玩家潜意识里判断一个游戏是不是业余 Demo 的关键。所以在 Echo Orb 的开发中我在每个模块完成后都回头把动画和音效补上。这篇日志就是把这些分散在各处的动画和音效实现整理在一起再加上中文字体适配这个让很多人卡住一整天的坑。二、Animator 的基础用法Bool 和 Trigger2.1 Animator Controller 是什么Unity 的动画系统分三层。最底层是 Animation Clip就是一个动画片段比如走路 4 帧。中间层是 Animator Controller它像一个状态机管各个 Clip 之间怎么切换。最上层是 Animator 组件挂在 GameObject 上持有一个 Controller 引用。创建流程为Window → Animation → Animation 窗口 → 选中物体 → Create 新 Clip → 帧图拖进时间轴 → Project 里 Create → Animator Controller → 把 Clip 拖进 Controller 的橙色网格 → 给物体 Add Component → Animator → 把 Controller 拖进去。这个流程做了好几次之后就会变成肌肉记忆但第一次接触的时候确实很容易找不到窗口在哪。2.2 Idle 和 Walk 的切换Bool 参数Echo Orb 中大多数角色都有两个状态站着和走着。用 Bool 参数 isMoving 驱动切换// 在角色的 FixedUpdate 里bool moving h ! 0 || v ! 0;if (anim ! null)anim.SetBool(isMoving, moving);Animator 里的连线规则。Idle → Walk条件 isMoving true。Walk → Idle条件 isMoving false。Has Exit Time 不勾Transition Duration 0。Has Exit Time 不勾的意思是一旦条件满足立刻切换不等当前动画播完。走路和站立的切换要求瞬间响应不能有过渡期。Transition Duration 0 也一样不需要交叉淡入淡出。2.3 一次性事件Trigger 参数有些动画只需要播一次比如死亡。Bool 需要双向管理 true 和 false多了容易忘。Trigger 播完自动失效。野猪 Boss 的死亡动画就是用一个 die 的 Trigger 驱动的。在 Animator 里 Any State → 死亡动画条件就是 die Trigger。代码里只需要一行if (anim ! null) anim.SetTrigger(die);Trigger 本身不需要在代码里手动重置Unity 在动画播放结束后的下一帧自动把 Trigger 消耗掉。2.4 踩坑静态 NPC 报了 isMoving 不存在有些 NPC 只有一个 Walk 动画没有 Idle/Walk 切换。但 NPC 脚本里写了 anim.SetBool。Animator 里没有 isMoving 这个参数运行时报黄色警告。解决办法很简单不需要参数切换的就不要在代码里调 SetBool。NPC 只有一个 Walk 动画直接把它设为 Animator 的默认状态就行不需要任何代码驱动。这边建议Animator 参数不要盲目给每个角色都加上。角色有几个状态才需要几个参数只有一个动画的就不要多此一举。三、左右翻转flipX 为什么比改 Scale 好3.1 问题的起点2D 游戏中角色往左走时需要翻转图像。最常见的做法是改 transform.localScale.x 为负值来镜像翻转。这个做法在角色单独存在时完全没问题。但 NPC 头上有一个交互图标它是 NPC 的子物体。父级 Scale 翻成负的了图标也跟着翻了。结果就是那个小小的 E 提示变成了镜像的。3.2 用 flipX 代替改 Scale我们可以试着翻转 SpriteRenderer 的 flipX 属性而不是翻转整个 Transform。void FaceDirection(Vector2 dir){if (sr ! null Mathf.Abs(dir.x) 0.01f)sr.flipX dir.x 0;}flipX 只影响渲染出来的图像Transform 本身纹丝不动。子物体的位置、缩放、旋转全部不受影响。交互图标该怎么显示还怎么显示。这个经验适用于任何有子物体的角色。野猪用 flipX黄蜂用 flipXNPC 用 flipX。从那以后我再也没用改 Scale 的方式来翻面。四、Animator 的层级结构多部件角色怎么处理4.1 当角色有多个可动部件如果角色需要身体和武器分开做动画比如主角发射子弹时手臂有个独立动作那就需要 Animator 的 Layer 功能。给身体一个 Layer给武器一个 Layer各自独立播放。但在 Echo Orb 里所有角色都只有单层动画。主角的发射动作是子弹的 Trail Renderer 来体现视觉效果的角色本体不需要额外的手臂动画。这是在美术资源有限的情况下的一种取巧做法。4.2 动画帧的制作与导入Echo Orb 的动画帧基本上都是 AI 生成的 spritesheet。导入 Unity 后如果是一整张 spritesheet需要先切图选中图片 → Inspector → Sprite Mode → Multiple → Sprite Editor → Slice → Grid By Cell Size → 填每帧的宽高 → Apply。切完后在 Project 窗口展开图片会看到里面切出来的子 Sprite。把这些子 Sprite 全选拖进 Animation 窗口的时间轴就行了。五、音效系统两个方法覆盖所有场景5.1 AudioSource.PlayOneShot给持久物体用Unity 播放音效有两种主要方式。第一种是 AudioSource.PlayOneShot适用于已经有一个 AudioSource 组件的 GameObject比如玩家。// PlayerController 里if (audioSource ! null shootSound ! null)audioSource.PlayOneShot(shootSound);发射音效和死亡音效都打在玩家自己的 AudioSource 上。好处是不需要额外创建对象播放完自动结束。5.2 AudioSource.PlayClipAtPoint给临时物体用第二种是 PlayClipAtPoint适用于没有自己 AudioSource 的物体。Unity 在调用这个方法时自动在那个位置创建一个临时的 AudioSource播完即销毁。// 子弹弹射音效if (bounceSound ! null)AudioSource.PlayClipAtPoint(bounceSound, transform.position);子弹弹墙、敌人死亡这些事件都用的 PlayClipAtPoint。调用者不需要挂 AudioSource 组件。注意 PlayClipAtPoint 默认 3D 音效衰减会生效离摄像机越远声音越小。如果你的游戏是 2D 俯视角且不希望有距离衰减可以把音量调大或者在 Audio Project Settings 里把 Spatial Blend 拉到 2D。5.3 走路音效的循环播放走路音效是一个短循环片段。做法是给玩家挂第二个 AudioSource专门用于走路。把 clip 设成那个短循环音效、loop true、playOnAwake false。移动时 Play停下时 Stop。walkAudioSource gameObject.AddComponentAudioSource();walkAudioSource.clip walkSound;walkAudioSource.loop true;walkAudioSource.playOnAwake false;在 FixedUpdate 里if (moving !walkAudioSource.isPlaying)walkAudioSource.Play();else if (!moving walkAudioSource.isPlaying)walkAudioSource.Stop();5.4 音效素材从哪里来Echo Orb 的音效全部从免费音效网站下载。大家选用素材的时候记得看清每一个音效的使用备注防止需要授权或需要申明哦。六、中文字体TMP 怎么认识汉字6.1 问题英文正常中文全空白Echo Orb 的对话系统里用了 TextMeshPro。默认字体是 LiberationSans包含英文字符但不含中文。直接用的话所有中文字符渲染出来都是空白方块。我们可以先找一个中文字体文件。Windows 自带的微软雅黑就在 C 盘的 Windows 的 Fonts 目录下文件名 msyh.ttc。复制一份到 Unity 的 Assets 里。6.2 Font Asset Creator 的正确参数接着把 ttf 或 ttc 字体转成 TMP 的 SDF 格式。打开 Window → TextMeshPro → Font Asset Creator。Source Font File 选刚导入的微软雅黑。关键一步Character Set 下拉选 Unicode Range (Hex)在下方出现的输入框里填入 4E00-9FFF这是中日韩统一表意文字的基本区间涵盖绝大多数常用汉字。Atlas Resolution 设 2048 x 2048。如果你需要覆盖更多生僻字或同时覆盖日文假名就加 3040-309F 和 30A0-30FF。点 Generate Font Atlas稍等一会儿最后 Save 到 Assets 里。七、摄像机与地图的视觉细节7.1 地图边缘的颜色在动画和音效都处理好了之后博主又在摄像机上做了一些改动以优化视觉效果。摄像机限制了地图边界但边界之外如果只有 Unity 默认的蓝色背景视觉上会显得很突兀。最简单的处理是在 Main Camera 的 Camera 组件里把 Background 颜色改成接近地图主色调的深色。这样地图之外的区域至少不会太扎眼。7.2 Tilemap 的遮挡顺序Tilemap 画出来之后有时候角色会被地图覆盖住看不见。这是渲染顺序的问题。选中 Tilemap 的 Tilemap Renderer 组件把 Order in Layer 调成比角色小的值。角色 Sprite Renderer 的 Order in Layer 设成更大的数。这一点大家在搜索Tilemap有关教程时应该着重讲到了这一点大家可以多复习复习。八、这一篇教会我的经验为什么重要Bool 管持续状态Trigger 管一次性事件不要用 Bool 去管死亡动画Trigger 自动失效更安全flipX 代替改 Scale子物体的交互图标不会再跟着翻PlayOneShot 给持久物体PlayClipAtPoint 给临时事件子弹弹射和敌人死亡不需要额外挂 AudioSource走路音效用循环 AudioSourcePlay 和 Stop 控制不用每步都创建新对象TMP 中文要 Unicode Range4E00-9FFF 是汉字基本区间不能用默认的 Extended ASCIIAnimator 参数不要给不需要的角色只有一个 Walk 动画的 NPC 设为默认状态即可不需要代码驱动Has Exit Time 不勾才能瞬间切换走路和站立的切换需要零延迟再次强调本人只是一个目前在做一些自认为有意义的学习的小白此篇只是我个人的一些开发路径和观点。发布的目的是渴望得到一些指点同时也为想迈出游戏开发这一步的读者们一些小的方向。若有不对或不足之处恳请各位大佬指点迷津下一篇预告打包发布与面试那些事 —— 怎么把 Unity 项目变成别人能玩的 zip 包、itch.io 上传的全流程、GitHub 仓库怎么打理才像一个专业的作品集、面试时怎么用三句话讲清楚你的项目。这是本系列的最后一篇从项目到作品集我们把它收个尾。