作者:一个依然在路上的Unity开发者(2018-2025)
标签:#Unity3D #游戏开发 #程序员成长 #技术复盘
2016年我开发的第一个跑酷游戏,场景中塞满了300多个带有独立脚本的Cube。当需要调整跳跃力度时,我竟然在47个脚本中逐个修改public变量:
// 菜鸟写法(2016年的我)
GameObject.Find("Player").GetComponent().TakeDamage(10);
// 觉醒后的写法
[SerializeField] private Health _playerHealth;
public void Attack() => _playerHealth.TakeDamage(10);
避坑指南:
使用[SerializeField]替代公共变量
避免在Update中频繁调用GetComponent
ScriptableObject数据配置示例:
[CreateAssetMenu]
public class WeaponConfig : ScriptableObject {
public float attackRange = 5f;
public int baseDamage = 20;
public AudioClip hitSound;
}
经历过无数次NullReferenceException后总结的经验:
方法 适用场景 危险操作
Awake 组件间初始化 访问其他未初始化组件
Start 外部系统交互 耗时操作阻塞主线程
OnEnable 状态重置 依赖其他组件的完成状态
协程的正确打开方式:
IEnumerator DamageEffect() {
yield return new WaitForSecondsRealtime(0.5f); // 无视timeScale
// 特效逻辑...
yield return new WaitUntil(() => _isReady); // 条件等待
}
物理交互三原则:
永远在FixedUpdate中操作Rigidbody
碰撞矩阵要遵循"最小交互原则"
使用NonAlloc版本物理检测方法
// 高性能射线检测示例
RaycastHit[] results = new RaycastHit[5];
int hitCount = Physics.SphereCastNonAlloc(
origin, radius, direction, results, maxDistance
);
GC优化三大法则:
避免在循环中创建新对象
使用静态引用池
预分配数组空间
// 内存泄漏示例 vs 优化方案
void Update() {
// Bad: 每帧创建新数组
float[] temp = new float[1024];
// Good: 使用缓存数组
Array.Clear(_cachedArray, 0, 1024);
}
Shader兼容性检查清单:
所有数值声明精度
precision highp float; // GLES必须声明
避免使用discard指令
测试GLES2后备方案
输入系统统一方案:
var gamepad = Gamepad.current;
var keyboard = Keyboard.current;
float move = gamepad.leftStick.ReadValue().x;
if (keyboard.spaceKey.wasPressedThisFrame) {
Jump();
}
结语:在技术洪流中保持清醒
编辑器操作≠真实运行结果
过早优化是万恶之源
版本控制要精确到小时级
如果本文对你有帮助,请点赞⭐收藏关注三连支持!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。