Unity 常见报错与排查清单

这篇按 Console 报错和现象来查:先找第一条错误,再按类型看原因和检查项。


快速索引

报错 / 现象 优先查
NullReferenceException 空引用、Inspector 没拖、初始化顺序
MissingReferenceException 对象已 Destroy 还在访问
Missing Script 脚本类名、文件名、GUID、meta
Prefab 引用丢失 引用场景对象、移动资源、Prefab 变体
编译错误 语法、命名空间、asmdef、API 版本
包冲突 Package Manager、重复 DLL、版本不兼容
构建失败 平台模块、Player Settings、插件平台
UI 点不到 EventSystem、Raycast、遮挡、interactable
动画不播 Animator、参数、Transition、Avatar
碰撞不触发 Collider、Rigidbody、Layer Matrix、IsTrigger
Raycast 打不到 LayerMask、距离、方向、Collider
Editor 正常打包不正常 大小写、平台宏、IL2CPP、资源路径

0. 通用排查流程

1
2
3
4
5
6
7
8
9
复制完整错误
找 Console 第一条错误
双击跳到自己的代码行
看这一行哪些对象可能为空
检查 Inspector / Prefab 引用
检查生命周期顺序
检查最近改动
最小场景复现
修复后重新进入 Play / 重新构建

1. NullReferenceException

含义:

1
访问了 null 对象

常见原因:

1
2
3
4
5
6
Inspector 引用没拖
GetComponent 返回 null
Find 没找到对象
Awake / Start 顺序不对
对象还没生成
对象已销毁

防御:

1
2
3
4
5
6
7
8
9
private void Awake()
{
if (player == null)
{
Debug.LogError("player 引用未设置", this);
enabled = false;
return;
}
}

组件获取:

1
2
3
4
if (!TryGetComponent(out Rigidbody rb))
{
Debug.LogError("缺少 Rigidbody", this);
}

2. MissingReferenceException

含义:

1
Unity 对象已经被 Destroy,但脚本还在访问旧引用

常见原因:

1
2
3
4
5
Destroy(obj) 后继续访问
协程等待后对象被销毁
async await 回来后对象被销毁
事件未解绑,旧对象还收到回调
对象池回收后旧引用仍在使用

防御:

1
2
3
4
5
6
await LoadAsync();

if (this == null || gameObject == null)
{
return; // await 后对象可能没了
}

事件清理:

1
2
3
4
private void OnDisable()
{
GameEvents.PlayerDied -= OnPlayerDied; // 禁用时解绑
}

3. Missing Script

常见原因:

1
2
3
4
5
脚本文件被删除
类名和文件名不一致
脚本移动时 .meta 丢失
namespace 改了
编译错误导致脚本无法加载

检查:

1
2
3
4
5
Console 是否有编译错误
脚本文件名是否等于 MonoBehaviour 类名
.meta 是否还在
Prefab / Scene 上哪个组件 Missing
是否最近改过 namespace 或 asmdef

4. Prefab 引用丢失

常见原因:

1
2
3
4
5
Prefab 引用了场景对象
移动资源时 .meta 丢失
Prefab Variant 结构变化
脚本字段重命名
序列化字段类型改变

字段重命名保引用:

1
2
3
4
using UnityEngine.Serialization;

[FormerlySerializedAs("oldName")]
[SerializeField] private Transform newName; // 字段改名时保留旧序列化数据

5. 编译错误

常见检查:

1
2
3
4
5
6
7
8
缺少 using
namespace 写错
类名重复
方法签名写错
括号或分号缺失
Unity API 版本不支持
Editor API 写进 Runtime
asmdef 引用缺失

Editor API 隔离:

1
2
3
#if UNITY_EDITOR
using UnityEditor;
#endif

Editor 文件夹:

1
Assets/_Project/Editor/xxx.cs       # 只在编辑器编译

6. Package / 插件冲突

常见现象:

1
2
3
4
5
类型重复定义
DLL 重复
包版本不兼容
asmdef 引用缺失
插件只支持某些平台

检查:

1
2
3
4
5
6
Package Manager 版本
manifest.json
Packages/packages-lock.json
Assets/Plugins 下是否有重复 DLL
插件 Inspector 的平台勾选
asmdef 依赖关系

7. 构建失败

优先查:

1
2
3
4
5
6
7
8
Build Settings 平台是否正确
目标平台模块是否安装
Player Settings 是否配置完整
Company Name / Product Name
包名 / Bundle Identifier
签名 / Keystore / Provisioning
插件平台兼容性
StreamingAssets / Addressables 是否构建

常见问题:

1
2
3
4
5
Android SDK / Gradle 错误
iOS Xcode 签名错误
IL2CPP 裁剪反射类型
资源路径大小写问题
Editor API 进入 Runtime

8. UI 问题

UI 点不到:

1
2
3
4
5
6
场景是否有 EventSystem
Canvas 是否有 GraphicRaycaster
按钮 interactable 是否为 true
上层透明 Image 是否挡住
Raycast Target 是否误开
Canvas Sorting Order 是否正确

UI 错位:

1
2
3
4
5
6
Anchor 是否正确
Pivot 是否正确
Canvas Scaler 是否正确
Safe Area 是否处理
父节点缩放是否异常
是否用世界坐标改 UI

9. 动画问题

动画不播:

1
2
3
4
5
6
Animator 是否启用
Controller 是否赋值
状态机是否有默认状态
参数名是否拼错
Transition 条件是否满足
动画 Clip 是否为空

动画事件不触发:

1
2
3
4
5
方法名是否一致
方法是否 public 或可被调用
参数类型是否支持
Clip 是否真的播放到事件帧
对象是否禁用

10. 物理问题

碰撞不触发:

1
2
3
4
5
6
双方是否有 Collider
至少一方是否有 Rigidbody
IsTrigger 和 OnTrigger / OnCollision 是否匹配
Layer Collision Matrix 是否允许碰撞
Rigidbody 是否 Kinematic
物体速度是否过快穿透

Raycast 打不到:

1
2
3
4
5
6
方向是否正确
距离是否足够
LayerMask 是否包含目标
目标是否有 Collider
是否从 Collider 内部发射
是否打到了前面的遮挡物

11. Editor 正常,打包异常

常见原因:

1
2
3
4
5
6
7
路径大小写不一致
用了 UNITY_EDITOR 包住之外的 Editor API
Resources / StreamingAssets 路径平台差异
IL2CPP 裁剪反射类型
插件平台未勾选
Addressables 没构建
目标平台权限缺失

12. 报错记录模板

1
2
3
4
5
6
7
8
9
10
11
报错全文:
第一条错误:
堆栈行号:
复现步骤:
复现概率:
平台:
Unity 版本:
最近改动:
怀疑原因:
验证方式:
修复结果:

13. 常见坑速查

1
2
3
4
5
6
7
只看最后一条错误                    # 第一条通常是根因
修了 Scene 忘了 Apply Prefab # Prefab 仍然错
删除 .meta # 引用丢失
Editor API 写进 Runtime # 构建失败
大小写路径在 Windows 正常 # Android/iOS 可能失败
字段改名没 FormerlySerializedAs # Inspector 引用丢
只测 Editor 不打包 # 平台问题漏掉

系列导航