ARTICLE DETAIL

建站实战干货

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

Unity期末作业实战:第三人称漫游完整工程与避坑指南

2026/9/26 12:12:53 拓冰建站 浏览量
Unity期末作业实战:第三人称漫游完整工程与避坑指南 简介一份基于Unity 2021的第三人称漫游场景期末大作业面向正在学习Unity游戏开发的学生或需要完成结课设计的开发者覆盖角色控制、场景建模、UI交互等关键环节可帮助理解第三人称视角、碰撞检测和输入映射。资源为zip压缩包约113MB共2000个文件以C#脚本、FBX模型、Prefab预制体、材质、Anim动画、Shader着色器及场景文件为主并配有UGUI菜单和音频素材目录结构清晰便于按模块直接学习或复用。目前已有2990人学习下载适合作为结课作业模板、课程设计参考或独立实践项目。项目中包含山谷、房屋、桌椅等精致场景模型支持鼠标控制小狐狸移动实现了血条、菜单、按钮等完整UI交互通过CharacterController、Input Manager与Unity UI的配合可体验从角色操控到界面反馈的完整游戏逻辑对学习URP渲染、PBR材质和Unity项目组织方式很有帮助。1. Unity期末作业做第三人称漫游为什么这个组合最不容易翻车期末周里最常见的 Unity3D 大作业不是玩法复杂的 RPG而是“第三人称漫游 精美场景”这种看起来简单、做起来要命的组合。这份资源正好卡在这个点上Unity 2021 版本做的完整工程场景里有山谷、房屋、桌椅等模型玩家用鼠标控制一只小狐狸在地图里转悠头顶有血条界面上有菜单和按钮。它适合两类人一类是第一次拿 Unity 做期末作业、想找一条完整链路照着走的在校生另一类是基础脚本已经会写、但想知道别人怎么组织场景和 UI 的开发者。它能替你把“场景搭建—角色控制—交互反馈”这三段最难串联的流程先跑通剩下的修修改改都比从零开始省事。我提前打个预防针它不是打开就出大片的一键工程模型精度和商业项目有距离但胜在链路完整。你能看到的是从场景布局怎么走到角色操控、再到 UI 反馈的完整闭环这个才是期末作业真正值分的地方。你也正好可以从这个工程里反推一套自己的实现习惯应付完作业之后改成自己的毕业设计底座也没问题。2. 场景搭建与模型导入山谷、房屋与桌椅的完整落地流程2.1 模型从哪来自带图元、Asset Store 还是外部建模Unity 期末作业最常见的误区是一上来就开 Blender 或者 Maya 建模结果时间全耗在模型上Unity 里的逻辑一点没动。实际做这种第三人称漫游场景模型来源可以分三层判断山谷这类大面积地形用 Terrain 工具直接刷房屋、桌椅这种静态物件用现成 FBX 模型导入后摆放角色模型则优先找带骨骼的现成资源因为后面如果要加跑跳动画带 Avatar 的模型才方便。我们来看这两类模型的处理原则。山谷部分大概率是在 Unity 的 Terrain 上通过高度笔刷生成的刷起来手感类似 Photoshop 的画笔可以控制笔刷大小和力度房屋和桌椅则作为 FBX 或 OBJ 模型导入后在场景里调整位置和角度。导入时有两个关键参数容易把人坑进去一是 Scale Factor 别乱动FBX 模型单位通常是米但 Blender 里可能是厘米这时在 Model 页签里把 Scale Factor 改成 0.01 或者在导入设置里统一换算不要在场景里直接放大缩小 GameObject否则碰撞体、光照烘焙结果和位置全部跟着乱二是碰撞体统一处理桌椅这类小物件不需要 Mesh Collider 这种精确碰撞用 Box Collider 包一个近似体就够了房屋的门框、墙体用多个 Box Collider 拼合摄像机跟随角色的时候才不会穿墙。模型类型推荐来源理由地形山谷、坡地Unity Terrain 工具直接刷自带高度图、植被系统和物理碰撞生成改起来最快建筑和静态物体房屋、桌椅Asset Store 免费包或外部模型导入FBX 格式导入后调整比例即可不卡壳角色小狐狸现成带骨骼的模型后续如果要加动画带 Avatar 的模型才方便2.2 场景布置的基本顺序地形→建筑→摆设→角色布置顺序会影响后期的工作量。我一般会强制按“先地形、再建筑、再摆设、最后角色”的顺序来操作理由很简单角色要放在建筑附近和道路上如果先放了角色再调地形高度一改角色就悬浮或陷进去了。具体步骤走一遍下面这套流程基本不会乱1. 新建场景通过菜单 GameObject - 3D Object - Terrain 创建地形 2. 在地形 Inspector 的 Terrain Settings 里把分辨率降到 512 或 256绘制速度会快很多 3. 用 Raise or Lower Terrain 刷出山谷的高度起伏再用 Set Height 压平建筑区 4. 导入房屋、桌椅模型按网格线摆放到地面用 Plane 或 Floor 判断是否水平 5. 摆好后用相机从第三人称高度浏览一遍把挡视野的树木、柱子移走 6. 最后把狐狸模型放到出生点并设定出生点朝向分辨率这里很多人容易忽略。地形分辨率默认可能到 1024刷起来非常卡降到 512 对期末作业精度完全够保存文件也更小。压平建筑区这个操作也很关键否则房屋放在坡上看起来像歪着盖的。摆放的时候还有个人经常翻车的点一个一个模型手动调位置太费时间。常见做法是先在场景里放几个空 GameObject 作为分组容器名字取成 Buildings、Furniture、Trees把模型拖进对应分组这样后期如果觉得整个山谷布局要平移只需要移动父物体。2.3 光照与材质让场景“精美”的第一层滤镜场景模型再好光照不对也会看起来很“平”。Unity 2021 里默认的渲染管线和 URP 在灯光配置上有差别但通用的做法是一样的主光源用 Directional Light补光用环境光或一盏低强度的 Point Light。核心参数建议按下面这张表去调这是让山谷看起来有层次的底线设置参数建议值说明Directional Light Rotation40 度左右俯角角度太低阴影太长太高画面发白Shadows TypeSoft Shadows硬阴影在低面数模型上会有明显锯齿边Ambient Mode用 Skybox 或固定环境色避免山谷背阴面黑成一片Material Metallic0 到 0.2木头、砖墙的金属度不要拉高否则像塑料亮面对桌椅和房屋这类场景对象PBR 材质不要直接滥用默认的白色 Standard。把 Albedo 换成带纹理的贴图Metallic 拉到 0.1 左右Smoothness 按材质类型区分木头 0.3、石头 0.2、窗户玻璃 0.8。这一层调完整个场景立刻会有“落过地”的感觉。光照还有一个性价比极高的操作在 Window - Rendering - Lighting Settings 里关闭 Auto Generate手动点一次 Generate Lighting。这个操作比较吃 CPU但点完之后阴影会变柔和山谷的明暗关系也会正常算是用一次等的时间换整个场景的质量。3. 角色控制与摄像机跟随让鼠标驱动小狐狸流畅移动3.1 CharacterController 为什么比 Rigidbody 更适合漫游第三人称漫游和动作游戏不一样它不需要真实的物理反弹也不需要敌人把你撞飞。用 Rigidbody 做移动稍微加力不均匀角色就会滑步或卡碰撞体而 CharacterController 是专门为“人形角色在地面走”设计的它不响应刚体物理的力只通过 Move 或 SimpleMove 方法移动并提供 isGrounded 这种便捷判断接口。选 CharacterController 还有一个现实原因可控性好。答辩现场老师通常会问“你这里怎么判断角色踩在地面上”你用 isGrounded 回答比扯一堆刚体力学的力、扭矩更容易讲清楚。挂组件的步骤也很短新接触 Unity 的人按这个顺序操作即可1. 选中小狐狸的根节点 GameObject 2. 菜单 Component - Physics - CharacterController 3. 把模型自带的 Capsule Collider 删掉CharacterController 自带胶囊碰撞 4. 调整 Height 和 Radius让胶囊体大致包住狐狸身体 5. 新建脚本 FoxController.cs 挂到小狐狸身上注意 CharacterController 和 Rigidbody 不要同时挂在同一个根物体上否则角色会不停旋转乱走。如果模型内部的子物体本身带了 Collider保留没问题但根节点上一定只保留 CharacterController 这一套碰撞体系这是很多人一开始没搞懂的层级问题。3.2 鼠标控制小狐狸的移动与转向脚本与参数移动输入这部分本身不难但有一个很关键的取向问题玩家的“前进”到底是世界坐标的前进还是摄像机视角的前进。第三人称漫游一定要用摄像机方向做基准否则玩家按 W 时角色会朝任意方向滑走。常见做法是给角色一个 public Transform cameraTransform在 Update 里读取输入并把移动方向从摄像机空间换算到世界空间。代码逻辑见下面using UnityEngine; public class FoxController : MonoBehaviour { [Header(移动参数)] public CharacterController controller; public Transform cameraTransform; public float moveSpeed 5f; public float rotateSpeed 8f; public float gravity -20f; private float verticalVelocity; void Update() { // 读取键盘输入横向对应 A/D纵向对应 W/S float horizontal Input.GetAxis(Horizontal); float vertical Input.GetAxis(Vertical); // 摄像机空间的前方和右方去掉 Y 分量后归一化 Vector3 camForward cameraTransform.forward; camForward.y 0f; camForward.Normalize(); Vector3 camRight cameraTransform.right; camRight.y 0f; camRight.Normalize(); // 目标移动方向 摄像机前方 * 纵向输入 摄像机右方 * 横向输入 Vector3 moveDir camForward * vertical camRight * horizontal; if (moveDir.magnitude 0.1f) { moveDir.Normalize(); // 平滑转向到移动方向旋转速度 8f 左右手感比较跟手 Quaternion targetRotation Quaternion.LookRotation(moveDir); transform.rotation Quaternion.Slerp(transform.rotation, targetRotation, rotateSpeed * Time.deltaTime); // 用 CharacterController 移动速度乘 deltaTime 保证帧率无关 controller.Move(moveDir * moveSpeed * Time.deltaTime); } // 重力处理落地时给一个小的向下速度防止 isGrounded 误判 if (controller.isGrounded) { verticalVelocity -1f; } else { verticalVelocity gravity * Time.deltaTime; } controller.Move(new Vector3(0f, verticalVelocity, 0f) * Time.deltaTime); } }这里 moveSpeed 决定漫游的节奏5 适合看风景型场景想让演示节奏更快可以调到 8。rotateSpeed 控制转向顺滑程度8 到 12 之间都不错数字小了角色转身像迟滞大了又像甩头。鼠标在这套方案里的角色是控制摄像机朝向再由摄像机朝向换算角色的移动方向。如果你期望的是“鼠标直接控制狐狸朝向”也就是操作方式改成按住鼠标右键拖拽转向可以改成读Input.GetAxis(Mouse X)把横向鼠标增量转换成旋转角的增量再叠加到角色的 Y 轴旋转上。两种手感差异在小狐狸这种低矮角色上尤其明显最好在答辩前亲手试一圈选你更能表达清楚的一种。3.3 摄像机跟随第三人称视角的两个关键参数第三人称摄像机只要写对两点就成功了大半跟随目标和不穿模。跟随用 Transform 的位置插值写穿模靠摄像机自身碰撞检测解决。先看最常用的跟随脚本using UnityEngine; public class ThirdPersonCamera : MonoBehaviour { [Header(跟随参数)] public Transform target; // 要跟随的角色根节点 public Vector3 offset new Vector3(0f, 2.5f, -4f); // 摄像机在角色后上方的偏移 public float smoothTime 0.2f; // 平滑时间越小越灵敏 private Vector3 velocity; void LateUpdate() { // LateUpdate 在角色 Update 之后执行保证这帧的移动结果先算完再跟过去 Vector3 desiredPosition target.position offset; transform.position Vector3.SmoothDamp(transform.position, desiredPosition, ref velocity, smoothTime); transform.LookAt(target.position Vector3.up * 1.2f); } }offset 的 Y 值决定摄像机高度狐狸这种矮模型Y 取 1.5 到 2.5 合适offset 的 Z 值取 -4 到 -6 都能接受太小的话视野里角色占一大半。但摄像机一旦贴墙角色会被墙挡住。避免这种问题有两种常见方案简单方案是把摄像机挂上碰撞检测在 LateUpdate 里从角色往摄像机位置发射射线撞到墙面就把摄像机拉近到射线命中点。写法如下public class CameraCollision : MonoBehaviour { public float maxDistance 6f; public LayerMask obstacleLayer; // 只检测场景环境层避免误伤角色自身 private Transform target; void LateUpdate() { Vector3 startPoint target.position Vector3.up * 1.2f; Vector3 backDir -transform.forward; // 从角色头顶往摄像机方向打一条射线检测是否碰到场景碰撞体 if (Physics.Raycast(startPoint, backDir, out RaycastHit hit, maxDistance, obstacleLayer)) { transform.position hit.point backDir * 0.2f; } } }上面这段挂在摄像机上之后摄像机与角色之间的墙会触发射线命中摄像机被拉回来。注意要把家具、房子这些场景物体放在一个统一 Layer 上比如 Environment射线只检测这个 Layer避免狐狸自己的角色碰撞体把摄像机挡住。用 LayerMask 限制检测对象是必做项否则角色靠近墙壁时摄像机经常会抖动。这其实就是网络上一堆人争论的 LayerMask 与 Rendering Layers 的典型落地场景LayerMask 控制的是逻辑检测范围Rendering Layers 控制的是渲染可见性两者不要混为一个概念。4. 血条、菜单与按钮UGUI 交互系统的常见实现方式4.1 Canvas 的缩放模式血条和菜单放在哪个坐标系Unity 里的 UI 全部要挂在 Canvas 下面。做这份期末作业的时候建议把根 Canvas 的 Render Mode 设为 Screen Space - Overlay这种模式下 UI 始终覆盖在画面最上层不受摄像机位置影响。血条、菜单、按钮全部放在同一个 Canvas 下用子节点分组管理。真正容易忽略的是 Canvas Scaler 的设置把 UI Scale Mode 设为 Scale With Screen Size参考分辨率设置为 1920x1080。这样在 1440x900 或其他尺寸的演示屏上UI 会自动等比缩放不会出现按钮特别小或者文字被裁掉的问题。血条和菜单的分层还要考虑 UI 元素的渲染顺序。Canvas 里的子物体顺序越靠下渲染时越靠前。所以血条、按钮这类需要点击的控件要放在上层背景装饰图放在下层。如果你做了一个全屏的半透明遮罩又想让血条露出来就要把遮罩放在血条的下层或者在遮罩的 Image 组件上取消勾选 Raycast Target否则它会挡住后面的所有点击事件。4.2 血条的两种写法Slider 组件和 Image.fillAmount血条在 UGUI 里有两种常见实现。第一种最简单拖一个 Slider 到 Canvas 下删掉它的 Handle Slide Area只保留 Background 和 Fill Area方向改成 Left To Right用脚本改 Slider.value 即可。第二种是 Image.fillAmount 写法适合想要“异形血条”“竖形血条”这类效果。做法是创建一张 Image把 Image Type 设为 FilledFill Method 设为 Horizontal然后通过脚本控制 fillAmount 从 1 降到 0。using UnityEngine; using UnityEngine.UI; public class HealthBar : MonoBehaviour { [Header(血条设置)] public Image fillImage; // 血条填充图Image Type 设为 Filled public float maxHealth 100f; private float currentHealth; void Start() { currentHealth maxHealth; fillImage.fillAmount 1f; } public void TakeDamage(float damage) { // 用 Clamp 防止血量掉到负数或者超过上限 currentHealth Mathf.Clamp(currentHealth - damage, 0f, maxHealth); fillImage.fillAmount currentHealth / maxHealth; if (currentHealth 0f) { Die(); } } private void Die() { // 死亡状态禁用移动逻辑并显示结束菜单 GetComponentFoxController().enabled false; GameObject.Find(DeathMenu).SetActive(true); Cursor.visible true; Cursor.lockState CursorLockMode.None; } }fillAmount 的取值范围是 0 到 1所以每次受伤要除一下 maxHealth 转成比例而不是直接把当前血量值赋给 fillAmount。这个坑几乎每个第一次写血条的人都会踩赋值后发现血条瞬间空掉就是因为没做归一化。Slider 方案的优点是自带滑块背景和填充条不需要额外准备美术图fillAmount 方案的优点是更灵活异形和多段血条都能改。期末作业建议优先用 Slider因为演示时调节最小值和最大值更直观。4.3 菜单、按钮与暂停逻辑菜单部分的核心不是排版而是暂停逻辑和按钮事件绑定。主菜单按钮一般要完成两件事把 Time.timeScale 设为 1关闭菜单面板。暂停菜单则相反点“暂停”时 timeScale 0点“继续”时 timeScale 1。按钮事件的绑定有两种方式图形化方式在 Button 的 OnClick 面板里拖入对象引用选择一个方法脚本方式更利于代码复用也方便答辩时解释。using UnityEngine; using UnityEngine.UI; public class UIManager : MonoBehaviour { public GameObject mainMenu; public GameObject pauseMenu; public GameObject deathMenu; public Button startButton; public Button pauseButton; public Button resumeButton; void Start() { // 用 AddListener 把按钮点击事件绑定到对应的处理函数 startButton.onClick.AddListener(StartGame); pauseButton.onClick.AddListener(PauseGame); resumeButton.onClick.AddListener(ResumeGame); } void StartGame() { mainMenu.SetActive(false); Time.timeScale 1f; Cursor.lockState CursorLockMode.Locked; } void PauseGame() { pauseMenu.SetActive(true); Time.timeScale 0f; Cursor.visible true; } void ResumeGame() { pauseMenu.SetActive(false); Time.timeScale 1f; Cursor.visible false; } }这里有个很关键的细节Time.timeScale 0 之后在 Update 里用Input.GetMouseButton检测菜单点击会失灵因为 Update 会按 timeScale 决定是否执行。所以按钮事件一定要放在 Button 的 onClick 或 EventSystem 管理的事件系统里而不是写在 Update 的输入检测里。Cursor 的处理也不能省启动进入游戏时一般把光标隐藏并锁定到屏幕中央鼠标移动用于控制摄像机转向打开菜单时再恢复可见否则演示时老师发现鼠标指针不见了会直接问“你的鼠标去哪了”。这也是很多演示现场翻车的经典环节。4.4 给狐狸加伤害交互碰撞检测与掉血如果你想演示“被碰到掉血”的效果可以给场景里的危险物加一个标签为 Hazard 的碰撞体然后在血条脚本里用 OnTriggerEnter 做一次检测void OnTriggerEnter(Collider other) { if (other.CompareTag(Hazard)) { TakeDamage(10f); } }把这段脚本挂在狐狸身上时狐狸需要有一个带 Collider 的子物体且该 Collider 的 isTrigger 勾选中。注意区分CharacterController 的碰撞是物理碰撞不会触发 OnTriggerEnter触发检测要额外加一个胶囊 Collider 并设为 Trigger。这一点非常容易踩中角色和障碍物确实碰到了但脚本里的 OnTriggerEnter 一次都不执行原因就是没有单独加 Trigger 碰撞体或者 Trigger 勾在 CharacterController 的同一个对象上。CharacterController 本身不会发送 OnTrigger 回调这正是很多人觉得触发器是玄学的原因。5. 避坑指南角色卡墙、方向错乱、按钮失灵与阴影噪点的一次性排查5.1 角色在斜坡上抖成筛子现象小狐狸站在山谷缓坡上身体一直在轻微上下抖动走两步甚至直接卡在坡面上。原因CharacterController 处理斜坡时Move 方向是纯水平方向重力每帧单独作用两者在坡面上竞争导致抖动。解决把 gravity 调整为 -20f 而不是 -9.81f让角色更“贴地”同时把 Controller 的 Slope Limit 保持在 45 度左右不要调太高。运行状态下在 Inspector 里观察 isGrounded 是否频繁翻转如果是再配合一个技巧把落地时的 verticalVelocity 从 -1f 改成 -2f 到 -3f给角色一点向下的压合力。这个小参数基本能解决绝大部分坡面抖动。5.2 按 W 键角色横着跑现象面向南按 W小狐狸朝东或者朝奇怪的方向滑动旋转方向完全对不上。原因脚本里直接用new Vector3(horizontal, 0, vertical)作为世界坐标方向没有考虑摄像机朝向。玩家以为的“前”是屏幕上视野的前方跟摄像机 Y 旋转有关直接把输入映射到世界 Z 轴就会错位。解决采用第三节里写的方式先取cameraTransform.forward和cameraTransform.right去掉 Y 分量两两组合成 moveDir。这是第三人称漫游的标配逻辑不要走世界坐标系的捷径。代码里出现横向移动却按摄像机方向跑、却斜着跑基本都是这里的问题。5.3 按钮和血条在运行时点不响现象按钮高亮效果都有但鼠标点击无响应血量掉到 0 之后菜单没有弹出。原因场景没有 EventSystem或者 Canvas 上有一个全屏 Image 把射线挡住了。UGUI 的射线检测必须依赖 EventSystem没有它任何按钮事件都不触发。解决在场景里右键 - UI - Event System 创建一个然后把 Canvas 下挡在最上层的大图的 Raycast Target 勾选去掉。血条本身如果是 Slider 自带的 Background Image它也会挡住底层按钮同样把 Raycast Target 去掉。判断依据很简单在 Game 视图里用鼠标点一下按钮看 Inspector 里的 Button 有没有触发状态变化没有就检查 Raycast Target 和 EventSystem 是否存在。5.4 场景阴影闪烁山谷像长了斑现象运行场景后房屋和树木的阴影边缘出现噪点状闪烁稍微移动摄像机角度暗纹位置还会跳变。原因默认 Quality 设置里 Shadow Distance 太大或者阴影分辨率不足。角色离阴影较远时Unity 会用低质量的阴影图边缘就开始闪。解决在 Project Settings - Quality - Shadows 里把 Shadow Distance 从 100 降到 30 到 40。再往下一层 Shadow Resolution 选 Medium 或 High。如果建筑区的阴影还是闪烁可以单独把建筑物设为 Static再重新烘焙 Lightmap。这个排查顺序最省时间不要一上来就去调材质的法线贴图。5.5 从编辑器切到打包出的程序场景模型全变灰现象在编辑器里山谷和房屋的贴图都正常Build 之后模型变成灰色或者白色。原因最常见的原因是模型贴图路径被锁定到了外部绝对路径打包时 Unity 找不到原始贴图另一个原因是材质球用到了项目外的资源Build 时被剥离。解决检查模型在 Inspector 里的 Materials 页签把材质球引用全部改为项目内的材质。再检查贴图 Texture 的 Read/Write 是否开启以及该贴图是否被加入 Build 的 Always Included Textures 列表里。做一次 PC/Mac/Linux Build输出后看 Log 中是否有 Missing 资源。这一步是很多人在答辩前一天才发现的属于最容易让人措手不及的一类问题建议提前两天就跑一次完整打包。6. 答辩前冲刺用三个细节把作业变成作品6.1 把摄像机 SmoothDamp 换成 Cinemachine如果工程时间还够优先引入 Unity 自带的 Cinemachine。它会直接解决两类问题摄像机跟随的阻尼手感、以及墙后的自动拉近距离。安装方式Window - Package Manager 搜索 Cinemachine安装后右键创建 CM FreeLook Camera把 Follow 设为小狐狸的根节点Look At 设为狐狸头部的空物体。Cinemachine 的 Orbital Transposer 模式天然带“绕角色旋转”的视角鼠标输入可以直接驱动它。这个方案演示效果比手写的 SmoothDamp 顺很多也是现在比较标准的 Unity 摄像机跟随实现路径。6.2 给山谷加一点“活着”的对象山谷里有树木、桌椅全是静态对象时场景看起来就是一栋模型的展示。加两个动态元素氛围立刻不同窗帘或树叶的 Animation 循环摆动或者一个点光源模拟烛火的大小闪烁。这类小动画不用写逻辑用 Animation 窗口录制一个循环片段调好循环时间两分钟就完成。注意把循环动画的 Wrap Mode 设为 Loop否则播完一次就停在最后一帧不动。这就是很多作业“看起来精致”和“看起来静态”的分水岭。6.3 最后强制走一遍这个验收清单答辩前把所有大项按顺序跑一遍逐个勾掉不要跳项1. 从主菜单进入游戏确认光标锁定、角色出生点正确 2. 漫游完整地图确认没有穿模死角摄像机不会撞墙 3. 触发一次掉血确认血条数值下降 4. 血量归零确认死亡菜单弹出角色停止移动 5. 菜单暂停后恢复确认 timeScale 恢复为 1 6. Build 一次 exe从头到尾跑这个流程这套流程不仅能帮你提前发现丢资源或按钮事件失灵的问题还会让你在答辩时对每个功能点的回答都有底气。确认基本链路没问题再去调材质、调阴影、调摄像机距离。我是那种反复被期末答辩现场坑过的人模型看得很漂亮但演示到一半角色卡在墙角、菜单按钮点了弹不出来那种场面真的很难受。从那以后我做任何 Unity 期末作业都会强制走一遍上面这个清单把基本链路理清楚再去谈精美希望帮到你。本文还有配套的精品资源点击获取