「如果敵人距離玩家 100 米外,它不需要思考、不需要動畫、不需要物理檢測——它只需要睡覺。」
void Update() {
if (Vector3.Distance(transform.position, target.position) > 100) return;
// 真正的邏輯...
}
缺點: Unity 仍每幀呼叫 Update、計算距離、分支預測失敗、GC 壓力,成百上千個敵人會拖垮主執行緒。
| 模式 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| OnBecameVisible / OnBecameInvisible | 渲染相關物件 (敵人、拾取物、特效) | 零成本、自動綁定相機視錐體剔除 | 相機不看就不啟用,適合「需畫面可見才活動」邏輯 |
| Trigger Collider (OnTriggerEnter/Exit) | 區域觸發 (任務區、戰鬥區、陷阱) | 精確控制觸發範圍、支援多層級 Tag 過濾 | 需額外 Collider、Rigidbody (isKinematic)、物理引擎開銷 |
| Coroutine 定期檢查 | 全域邏輯 (AI 決策、資源採集、狀態機) | 可精確控制頻率 (如 0.2 秒/次)、可 yield 等待條件、極低 CPU | 需手動管理啟停、邏輯分散在協程中 |
// 基礎:每幀 yield
IEnumerator Patrol() {
while (true) {
DoPatrolLogic();
yield return null; // 等待下一幀
}
}
// 定時:每 5 秒執行
IEnumerator SlowCheck() {
while (true) {
CheckPlayerDistance();
yield return new WaitForSeconds(5f);
}
}
// 串聯:等待另一個協程完成
IEnumerator Sequence() {
yield return StartCoroutine(Phase1());
yield return StartCoroutine(Phase2());
// Phase2 結束後繼續
}
// 事件驅動:等待自訂事件 (配合 UniRx/EventSystem)
IEnumerator WaitForEvent() {
yield return new WaitUntil(() => GameManager.Instance.IsReady);
OnGameReady();
}
| 方案 | 主執行緒 ms/幀 | GC Alloc/幀 | 備註 |
|---|---|---|---|
| Update 輪詢距離 | 12.4 | 1.2 KB | 基準線 |
| OnBecameVisible 啟用 | 0.3 | 0 | 僅視野內 ~50 體活躍 |
| Trigger 區域啟用 | 0.5 | 0 | 物理引擎微小開銷 |
| Coroutine 0.2s 檢查 | 0.8 | 0 | 全域邏輯最優解 |
Renderer,用 OnBecameVisible 啟用 enabled = true。StartCoroutine(SlowCheck()) 替代 Update。BoxCollider isTrigger,掛載 OnTriggerEnter 啟用腳本。WaitUntil/WaitWhile 等待條件,避免空轉。Unity 效能優化不是玄學,核心只有兩句話:「不需要時別執行」、「需要時才喚醒」。掌握 Coroutine、事件驅動、視野剔除三板斧,90% 效能問題迎刃而解。