Unity 常见问题
47 questions that each have a pile of threads on Unity's official forum, answered here in full. Each one points to where the long version lives — a guide when it is a recipe, a lesson when it is a stage of the course.
怎么让角色移动?
三种方式里只选一种,绝不同时用两种:由你直接操控的玩家用 CharacterController,需要靠物理推动的物体用 Rigidbody,而 transform.Translate 只用于不发生碰撞的物体。所有速度都要乘以 Time.deltaTime,否则机器越快、游戏跑得越快。
指南 · 17.09.2026移动角色:三种方式里哪种适合你8 分钟 →怎么让角色跳跃,并阻止它在半空中再次起跳?
跳跃本身只有一行代码;难的是判断脚什么时候踩到了东西。用角色正下方一个小球去和 Ground 层做检测,只有检测返回 true 时才允许起跳。绝不要去判断竖直速度是否为零——在抛物线的最高点它同样是零。
指南 · 17.09.2026跳跃,以及让它正确的落地检测9 分钟 →怎么旋转一个物体,Quaternion 是什么?
当你已经知道想要的角度时,用 Quaternion.Euler(x, y, z);要转向某个目标,就用 Quaternion.LookRotation 配合 RotateTowards 或 Slerp。绝不要直接往 transform.rotation 上做加法:它存的是四个并非角度的数,把角度写进去只会得到无意义的结果。
指南 · 17.09.2026旋转:欧拉角、四元数,以及哪个你能碰11 分钟 →怎么让相机平滑跟随玩家、不抖动?
在 LateUpdate 里移动相机,绝不在 Update 里:LateUpdate 在所有其他东西都移动完之后才运行,所以相机读到的是已经定稿的位置。如果玩家用了 Rigidbody,还要把 Rigidbody 的 Interpolate 选项设为 Interpolate——物理的 tick 频率和你的帧率并不一致。
指南 · 17.09.2026不卡顿的跟随相机8 分钟 →怎么判断玩家正在瞄着什么、或站在什么上面?
Physics.Raycast 射出一条看不见的线,并报告它碰到的第一个 collider,附上命中点、距离和表面法线。一定要传入 LayerMask 和最大距离——否则射线会对所有层一直检测到无穷远,而从第三人称相机射出的射线会先打中正前方的玩家自己。
指南 · 17.09.2026射线检测:问世界你面前有什么10 分钟 →怎么用代码生成物体?
把要生成的东西做成 prefab,在一个 public 字段里持有对它的引用,然后调用 Instantiate(prefab, position, rotation)。把 Prefab 从 Project 面板拖进那个字段——拖成 Hierarchy 里那个场景实例,是一半生成器 bug 的根源。
指南 · 17.09.2026Instantiate:生成 prefab 并复用它9 分钟 →怎么让一件事随时间逐渐发生,或者先等待再执行?
协程是一个可以暂停的方法:yield return new WaitForSeconds(1f) 等一秒,然后从同一行继续往下跑。用 StartCoroutine 启动它,如果将来需要停止就保留它的句柄;并记住:当运行该协程的 GameObject 被禁用或被销毁时,协程会停下。
指南 · 17.09.2026协程:不用 Update 也能随时间做一件事10 分钟 →怎么让 UI 适配所有屏幕尺寸?
把 Canvas Scaler 设为 Scale With Screen Size 并给一个参考分辨率,然后把每个元素锚定到它该在的角或边,而不是让它一直锚在中心。在有刘海的手机上,让一个全屏父物体去贴合 Screen.safeArea,这样重要的东西就不会被切到刘海底下。
指南 · 17.09.2026适配所有屏幕的 UI,包括刘海屏11 分钟 →怎么保存玩家的进度?
零星的设置用 PlayerPrefs,真正属于游戏状态的东西则用 Application.persistentDataPath 下的一个 JSON 文件来存。在 OnApplicationPause 和 OnApplicationQuit 里都要写文件——在手机上,Quit 往往根本不会被调用。
指南 · 17.09.2026保存进度:PlayerPrefs、JSON,以及各自适用的场景9 分钟 →怎么构建 APK 并装到 Android 手机上?
安装 Android Build Support 模块,把平台切换到 Android,设置一个属于你自己的包名,然后构建。挡住大多数初次构建的,往往是 Unity 找不到的 SDK 或 JDK 路径;之后才咬人的,是用默认的 com.DefaultCompany 包名发布——因为应用一旦上了 Google Play,包名就永远改不了了。
指南 · 17.09.2026从项目到真机上的 APK10 分钟 →为什么我的角色会直接穿过地面掉下去?
有四种原因,按值得排查的顺序:地面没有 Collider;两个 Collider 里有一个勾了 Is Trigger;物体在一个物理步长里移动得太远,直接越过了很薄的地面——而 Plane 永远都是薄的;或者这两个层在 Collision Matrix 里被互相取消了勾选。用 CharacterController 时还有第五种:用 transform.position 而不是 Move() 去移动它,会完全跳过碰撞检测。
课第一个场景:一片平的 3D 地面基础 →NullReferenceException 是什么意思?
你用了一个为空的变量。在 Console 里双击那行红字,它就会打开抛异常的那一行;在那一行上,某个点号左边的东西是 null。最常见的元凶是 Inspector 里某个没人往里拖东西的槽位,它显示为 None,行为上就等于 null。
课类即组件基础 →为什么我的 public 变量没有显示在 Inspector 里?
先看 Console:只要项目里还有任何脚本编译失败,Unity 就会继续运行上一次编译成功的版本,于是你刚加的字段在你的文件里,却不在 Unity 正在运行的那份里。否则就是类名没有和文件名完全一致,或者这个类型是 Unity 无法序列化的——比如 Dictionary、接口,或带 get 和 set 的属性。
课类即组件基础 →为什么 OnTriggerEnter 从来不被调用?
必须四个条件同时成立:两个物体中至少一个有 Rigidbody;两个 collider 中至少一个勾了 Is Trigger;方法名精确地写成 OnTriggerEnter 且接受一个 Collider 参数;这两个层在 Collision Matrix 里被互相启用。CharacterController 是第一条件的例外:只要用 Move() 去移动它,即使没有 Rigidbody 它也会发出 trigger 消息。
指南 · 20.09.2026碰撞与触发器:为什么事件从不触发9 分钟 →怎么切换到另一个场景?
把每个场景都加进 File > Build Profiles 里的 Scene List,然后用场景名调用 SceneManager.LoadScene。切换发生在下一帧,旧场景里的一切都会被销毁,只有标记了 DontDestroyOnLoad 的根物体能存活——以及静态字段和 Time.timeScale,这些没有任何人会替你重置。
指南 · 20.09.2026切换场景:LoadScene、加载界面,以及什么会存活下来10 分钟 →单例是什么,GameManager 应该怎么写?
单例就是一个存活的对象,配一个指向它的静态字段,于是任何脚本都能调用 GameManager.Instance 而无需自己持有引用。在 Awake 里给该字段赋值,在 Start 里读取它,销毁重新加载场景时带进来的第二个实例,并且只有当这个 manager 确实必须活得比场景更久时才调用 DontDestroyOnLoad。
指南 · 20.09.2026单例:整个游戏都能访问的一个 GameManager9 分钟 →Unity 里的 prefab 是什么?
Prefab 是一个被存成文件、放在 Project 面板里的 GameObject;场景里的所有副本都跟随它,所以改这个文件会一次改掉每一个副本。若你去改某个副本,那处改动只是该副本上的一个 override——以粗体显示,并可在 Overrides 下拉里用 Apply All 和 Revert All 处理。
指南 · 20.09.2026Prefab:源文件、副本,以及二者之间的修改8 分钟 →为什么手机提示“应用未安装”?
几乎总是签名冲突:这个包名已经以另一把 debug key 构建的版本装在机里了。先跑 adb uninstall com.yourstudio.yourgame 把它卸掉再装 —— 手机上的存档也会跟旧版一起没掉。
指南 · 22.09.2026APK 装不上手机:每条报错逐个讲原因11 分钟 →“解析软件包时出现问题”是什么意思?
意思是安装器完全没能读懂这个 APK:文件在传输时被截断或改名、有人把 .aab 改成了 .apk、Minimum API Level 高于设备、或者只有 ARM64 的构建装到了 32 位手机上。先跟电脑上那份对一下字节数,因为这一步只要十秒。
指南 · 22.09.2026APK 装不上手机:每条报错逐个讲原因11 分钟 →为什么 Unity 游戏在 Android 上一打开就闪退?
先跑 adb logcat -s Unity 再启动游戏:原因几秒内就会打出来,而带文件名和行号的堆栈跟踪说明是你自己 C# 的问题 —— 多半是某个 scene 没加进 Build Profiles,或者 Inspector 里有个引用没设。要是一条 Unity 都没有,就用 Managed Stripping Level 设为 Minimal 重建一次,很可能是 IL2CPP 把只有 reflection 能摸到的类型删掉了。
指南 · 22.09.2026APK 装不上手机:每条报错逐个讲原因11 分钟 →为什么 Unity 游戏在 Android 上黑屏,在 editor 里却正常?
因为手机启动的是 Build Scenes 里 index 0 那个场景,而不是你当前打开的那个;而且不在列表里的场景根本不会被打进包。于是你的 LoadScene 只留下一行日志就失败了,本该被替换掉的菜单还躺在那里。先检查列表再去碰渲染设置,并让 adb logcat 把原因念出来。
指南 · 22.09.2026编辑器正常、手机上一片黑12 分钟 →屏幕是黑的但能听见游戏在跑。这是什么问题?
逻辑活着、只是画面没了,所以要么是相机没东西可渲染,要么是 UI 把一切盖住了。先把 Canvas 的勾去掉构建一次:世界出现了就说明盖子是 UI。要还是没变化,就把 Clear Flags 设成 Solid Color、背景挑个扎眼的颜色再构建 —— 变粉说明相机视野是空的,仍然黑说明那个场景里没有启用中的相机。
指南 · 22.09.2026编辑器正常、手机上一片黑12 分钟 →在手机上材质变粉而不是变黑 —— 是同一个问题吗?
同一类问题,但坏的环节不同。粉色说明那个文件里没有支持该平台的 subshader,于是 Unity 画它的错误材质;黑色说明 shader 被收下了,只是那一刻需要的变体被裁掉或被驱动拒绝。在动任何材质之前,先关掉 Auto Graphics API,用不含 Vulkan 的 OpenGLES3 试一次。
指南 · 22.09.2026编辑器正常、手机上一片黑12 分钟 →Unity 的 CharacterController 不动,该从哪里开始?
挂一个每秒记录一次 input 向量的临时脚本,然后按 Play 并压住 W。有数字说明输入正常,惯犯是还停在 0 的 speed,因为 public float speed; 没有默认值。没有数字说明脚本根本没跑——object 被关、component 没勾选,或者项目用的是新 Input System,而代码在调 Input.GetAxis。
指南 · 22.09.2026CharacterController 不动:按成本从低到高的七项检查12 分钟 →为什么角色慢到几乎不动?
两种形态:speed 填成了 0.001 而不是 6,也就是一毫米每秒;或者该乘 deltaTime 却去除了它,甚至整个省掉。Move() 接收的是这一帧的米数,所以每秒米的 speed 必须乘 Time.deltaTime。去掉 deltaTime,同一个角色就变成了帧率相关——在 120 Hz 的手机上快一倍。
指南 · 22.09.2026CharacterController 不动:按成本从低到高的七项检查12 分钟 →角色会转身却不往前走,为什么?
旋转会忽略缩放,往前走不会,所以要查这个 Transform 和每层父级的缩放:任何轴为 0 或镜像负值,都会让 CharacterController 的 capsule 失去体积;被缩放的根节点会在数学以为能继续的地方把 Move 停下。Unity 要求该 Transform 是 1, 1, 1——模型尺寸请改到 importer 的 Model 页里设置。
指南 · 22.09.2026CharacterController 不动:按成本从低到高的七项检查12 分钟 →自学 Unity 到做出游戏要多久?
这门课共 40 课、合计 447 分钟=7.45 小时。把 5 道章末练习按题目自己标明的用时做完(60–90 分钟,再加 3–4、2–3、3–4、3–5 小时),真实合计就是 18–23 小时,相当于 35–46 个 30 分钟,每天学就是 1 到 2 个月。
指南 · 22.09.2026学 Unity 要多久?这门课自己的真实数字11 分钟 →每天 30 分钟够学 Unity 吗?
上一节课够用:平均 447 ÷ 40 = 11.2 分钟,只算课程正文是 447 ÷ 30 = 14.9 次,每天学约 2 周,每周 5 次就是 3 周。把练习加上,同样算法得到 35–46 次。
指南 · 22.09.2026学 Unity 要多久?这门课自己的真实数字11 分钟 →自己做一个游戏并发布要多久?
课程表里的数字答不了这个,因为它是范围问题而不是 Unity 问题。这门课能给的最接近的说法:第二个游戏若原样复用第 02 章和第 05 章练习教的东西 —— 移动、三个技能、会追击会反击的敌人、一个 APK —— 就是 6–9 小时,而且前提是美术素材已经有了。
指南 · 22.09.2026学 Unity 要多久?这门课自己的真实数字11 分钟 →Unity 是真免费,还是免费版只是个试用版?
它是正式授权档而不是试用版:不会到期、不用信用卡,也能发布商用游戏。条件是最近十二个月营收加融资不超过 20 万美元,以及没有 Pro 授权就不能构建主机平台。
指南 · 22.09.2026Unity 是免费的吗?免费版到底给你什么11 分钟 →Unity 现在还会按安装量收 Runtime Fee 吗?
不会。Unity 在 2024 年 9 月 12 日取消了 Runtime Fee,即时生效、不向任何游戏收费,并回到按席位订阅的模式。还在警告按安装收费的内容,全都写于那个日期之前。
指南 · 22.09.2026Unity 是免费的吗?免费版到底给你什么11 分钟 →我到底什么时候才需要买 Unity Pro?
当你所在机构最近十二个月的营收加融资超过 20 万美元,或者你必须发到 Switch、PlayStation、Xbox、Vision Pro 空间应用这类封闭平台时。学 Unity 和发布第一作都不在这些条件里。
指南 · 22.09.2026Unity 是免费的吗?免费版到底给你什么11 分钟 →做 Unity 游戏之前必须先会 C# 吗?
不用,但需要一点点:第一章用四节短课讲变量、方法、类和 if/for/List,这正好是第一个游戏会要的全部 C#。剩下的都是 Unity,而它是在你正在搭的那个项目里学会的。
指南 · 22.09.2026Unity 做 3D 游戏:五个阶段,只做一个项目11 分钟 →第一个 Unity 游戏要做多久?
这门课的 40 节课按引导做完大约 7.5 小时,而真正做完的诚实倍数是 2 到 3 倍:多出来的时间都花在构建、帧率以及只有你的项目才有的那些部分上。一个周末够你做出能玩的竞技场;走完五个阶段才变成手机上的游戏。
指南 · 22.09.2026Unity 做 3D 游戏:五个阶段,只做一个项目11 分钟 →多看教程和做完一个项目,哪个更好?
教程教的是游戏的中段,并且会在决定它能不能发布的东西之前停下——构建设置、真机、帧率。这些只存在于你自己的项目里,所以看十个教程的结果是:你能开始很多游戏,一个都做不完。
指南 · 22.09.2026Unity 做 3D 游戏:五个阶段,只做一个项目11 分钟 →挂了 Animator,动画却从来不播放,为什么?
卡住它的有三处,按这个顺序查。第一,GameObject 上要有 Animator 组件,并且 Controller 那一栏里要有 asset —— 空着不会播放任何东西,也不报错。第二,片段必须是 Controller 里的一个 state,并且其中一个要是橙色的默认 state;只躺在 Project 窗口里的片段永远不会被播放。第三,从默认 state 出去的 transition 要有一个你的代码真的会设置的条件:调用 SetTrigger("Attack") 的话,参数名就得写成 Attack、类型是 Trigger,而且 transition 必须用到它。让游戏跑着的同时打开 Animator 窗口 —— 正在播放的 state 会亮起来,缺的是三者中的哪一个,一看就知道。
课Animator 状态机角色与战斗 →怎么让敌人追着玩家跑并且攻击?
测一次距离就决定状态,状态再决定行为:超出仇恨范围就待机,进了范围就朝你走,到了手够得着的距离就按冷却挥击。测之前要把方向向量的 Y 压平,否则站在方块上的玩家会被读成离得很远。竞技场里有障碍物的话,用 NavMeshAgent 和 SetDestination,而不是自己挪 transform —— agent 会绕过方块,直线只会撞上去然后杵在那儿。
课会追击并反击的敌人角色与战斗 →带冷却的技能系统怎么做?
把技能当成数据,别让它是脚本。一个 ScriptableObject 存冷却、伤害、射程、图标、动画 trigger 和特效 prefab;释放技能的脚本只持有一个字典,从技能映射到「最早可以再用的时刻」。于是释放就是:Time.time 有没有过那个存下来的时刻,过了就播动画、生成特效、扣血,然后把 Time.time 加冷却再存回去。用 Time.time,别用每帧递减的倒计时变量 —— 一个数字,不会漂移,物体被禁用再启用也还是对的。
课带冷却的技能系统角色与战斗 →一次打出很多子弹游戏就卡顿,怎么解决?
卡顿来自 Instantiate 和 Destroy,不是子弹本身。每次 Destroy 都会给垃圾回收器留下垃圾,而回收器一跑就会卡住整整一帧。改成复用:在 Awake 里一次性建好一个子弹列表并全部设为不激活,每次开火就取一个不激活的,摆到位置上再激活;打中东西时把它设为不激活,而不是销毁。数量固定,游戏过程中不再分配内存,顿挫也就没了。
课弹道、伤害与特效角色与战斗 →新版 Input System 和 Input.GetKey 有什么区别?
旧的那套每帧直接问硬件,于是每种设备都要在代码里多一个分支,做改键界面几乎不可能。新的那套在中间放了一个 asset:你声明一个叫 Move 或 Jump 的 action,把键盘、手柄、触屏分别绑到它上面,而代码永远只读这个 action。以后要加手柄,改的是 asset,不是角色脚本。从 Package Manager 装上,迁移期间把 Active Input Handling 设成 Both,然后一次迁一个 action。
课全新的 Input System镜头与操作 →手机上的虚拟摇杆和按钮怎么做?
不要写第二条操作路径。让屏幕上的摇杆去推键盘推的那同一个 input action,角色脚本就永远不必知道触屏的存在。一个摇杆就是两张 Image —— 底座和摇头 —— 外加一个拖拽处理,把摇头相对中心的偏移变成一个长度不超过 1 的向量。把整层操作控件放进一个 Screen Space Overlay 的 Canvas,每个控件锚在自己的角上,有刘海的手机还要留出安全区。
课触屏操作与摇杆镜头与操作 →需要用 Cinemachine 吗,还是自己写的跟随相机就够了?
只是跟着角色走的话,自己写就够了,而且值得写一次,因为它会让你明白相机为什么属于 LateUpdate。Cinemachine 真正值钱的是下一步:按轴分别阻尼、用死区让小幅移动不带动相机、碰撞让视角不穿墙,以及为过场或瞄准模式在多台相机之间做混合。这些自己写要好几周,配置一下只要半个下午。学习阶段留着你自己的脚本,等到需要第二台相机时再换。
课Cinemachine 与镜头震动镜头与操作 →加了地形和灯光之后场景一片漆黑,怎么办?
改完东西之后变暗,几乎总是因为光照数据过期了,而不是灯本身有问题。打开 Window,再进 Rendering,再进 Lighting,按下 Generate Lighting;凡是标了 Static 的东西,在你重新烘焙之前都会一直保留烘焙当时的光。再查三样:Directional Light 是否启用、是否斜着朝下照而不是贴着地平线;skybox 是否还挂在 Environment 里;以及 Ambient 有没有被设成黑色。如果只有一部分物体是暗的,那它们是 static,而且是在没有灯的时候烘焙的。
课光照与天空盒世界与游戏循环 →在编辑器里很流畅,上了手机就掉帧,为什么?
编辑器跑在桌面 GPU 上,而且没有温度墙;手机两样都没有。动手改之前先测:出一个 development build,用 USB 接上 profiler,看这一帧究竟是卡在 CPU 还是 GPU。常见的就那四个:材质各自为政导致 draw call 过多、以 2048 导入但根本没人在那个尺寸下看的贴图、来自一盏以上灯光的实时阴影,以及忘了关的后处理。每秒 60 帧的预算意思是所有事情要在 16 毫秒内做完 —— 该决定的是把它花在哪,而不是随手乱砍。
课移动端性能预算导出到手机 →怎么让声音从某个位置发出,并且在一个地方统一调音量?
声音有了位置,是因为把 AudioSource 的 Spatial Blend 从 2D 拖到了 3D;留在 2D 的话它在哪儿都一样响,脚步声听起来像跟着相机跑就是这个原因。把 rolloff 距离设成在一个合理范围内衰减。至于音量,别一个个手动调:建一个 AudioMixer,分出音乐、音效、界面几个组,让每个 source 都走进对应的组,再把每组的音量 expose 成参数。这样设置里的一根滑条就能带动一整类,暂停时静音也只要一行。
课声音与氛围世界与游戏循环 →Unity 项目里,哪些该提交、哪些该忽略?
要提交的是 Assets/、ProjectSettings/ 和每一个 .meta 文件 —— .meta 里存着每个 asset 的 id,少了它,到下一台机器上引用就会变成 missing script。要忽略的是 Library/、Temp/、obj/、Build/ 和 Logs/:Unity 自己会重建,它们动辄好几个 G,而且每台机器都不一样。在任何人 clone 之前,先把 Version Control 设成 Visible Meta Files、Asset Serialization 设成 Force Text,否则场景文件一直是二进制,在 diff 里永远读不了。
指南 · 24.09.2026Unity 的 Git:该提交什么,该忽略什么10 分钟 →导入的模型特别小、躺着、或者一片惨白,是怎么回事?
这是三处互不相干的不一致,而且每一处都该在 importer 里改,而不是改 Transform。太小或太大是单位问题:在 Model 标签里勾上 Convert Units,或者对 Blender 的文件把 Scale Factor 设成 100。脸朝下趴着,是因为 Blender 以 Z 为上而 Unity 以 Y 为上:勾上 Bake Axis Conversion,或者导出前在 Blender 里 apply 一次旋转。惨白是因为 FBX 只带材质名字、不带图片:把贴图拷进工程,再按 Extract Materials,然后把各个槽填上。至于亮粉色则是另一回事 —— 那是缺 shader,通常是 URP 工程里混进了 Built-in 的材质。
指南 · 24.09.2026导入 3D 模型:缩放、旋转和丢失的贴图9 分钟 →