Unity 2D 粒子模擬系統 — 今日更新總結

已思考 2 秒鐘
在本次更新中,我們從架構、效能、物理到 UI,都進行了大規模的優化與功能擴充,包含:
模組化重構
效能優化五部曲
互動式 UI 強化
Collider2D 碰撞檢測
動態縮放與顏色漸變
邊界管理
以下依序詳述每個部分。
1. 模組化重構
ParticleManager.cs:集中管理粒子與標籤,採用物件池(Pool)技術。
GravitationalSystem.cs:只負責萬有引力計算,碰撞行為改由
HandleCollision
處理。ParticleCollisionHandler.cs:掛載於粒子預製體上,透過
OnCollisionEnter2D
把碰撞事件送入GravitationalSystem
。EnergyTracker.cs:動能統計與能量柱圖,改用 Coroutine + 物件池更新。
LogExporter.cs:粒子狀態與事件日誌輸出,重用
StringBuilder
避免 GC。SimulationController.cs:流程調度、啟動/暫停/重置、定時日誌輸出、FixedUpdate 節流。
SimulationUIBindings.cs:開始前、開始後 UI 分頁顯示,加入「暫停時開啟資料夾」按鈕。
BoundaryManager.cs:在主攝影機視野自動生成靜態牆,限制粒子不飛出畫面。
2. 效能優化五部曲
物理運算節流:
// SimulationController.FixedUpdate() private int physicsFrameCounter; public int physicsFrameThreshold = 2; private void FixedUpdate() { if (!hasStarted || isPaused) return; if (++physicsFrameCounter % physicsFrameThreshold == 0) gravitationalSystem.ApplyForces(); }
全面物件池化:
// ParticleManager.Awake() for (int i = 0; i < poolSize; i++) { var p = Instantiate(particlePrefab); p.SetActive(false); particlePool.Enqueue(p); }
GC 分配優化:
// LogExporter.cs private StringBuilder sbScreen = new(); private StringBuilder sbFile = new(); public void LogParticleStates() { sbScreen.Clear(); sbFile.Clear(); // … AppendLine … logOutputText.text = sbScreen.ToString(); File.AppendAllText(path, sbFile.ToString()); }
尾部交換移除法:
// ParticleManager.RemoveParticle(int idx) int last = activeParticles.Count - 1; if (idx != last) { activeParticles[idx] = activeParticles[last]; activeLabels [idx] = activeLabels [last]; } activeParticles.RemoveAt(last); activeLabels .RemoveAt(last);
Coroutine 定時更新:
// EnergyTracker.cs private IEnumerator EnergyLoop() { while (true) { yield return new WaitForSeconds(energyLogInterval); LogTotalKineticEnergy(); } }
3. 互動式 UI 強化
延遲啟動:按下「開始」前,只顯示兩個輸入框與開始鍵。
開始後:自動切換到完整控制介面(暫停/重置/速度滑桿/圖表/日誌)。
暫停時:顯示「開啟資料夾」按鈕,一鍵打開
Application.persistentDataPath
。
// SimulationUIBindings.cs 節錄
startButton.onClick.AddListener(OnStartClicked);
pauseButton.onClick .AddListener(OnPauseClicked);
openFolderButton .onClick .AddListener(OpenFolder);
private void OpenFolder() {
Application.OpenURL("file://" + Application.persistentDataPath);
}
4. Collider2D 碰撞檢測
將粒子預製體加上 CircleCollider2D
(IsTrigger=false
)和以下腳本,即可利用 Unity 物理自動偵測:
// ParticleCollisionHandler.cs
void OnCollisionEnter2D(Collision2D col) {
// 找到兩者索引 i, j …
gravSystem.HandleCollision(i, j, rb, otherRb);
}
並在 GravitationalSystem.HandleCollision 中,以「系統總動能」判斷後續行為。
5. 動態縮放與顏色漸變
// ParticleManager.CreateParticle()
float scale = baseParticleScale * Mathf.Pow(mass, 1f/3f);
p.transform.localScale = Vector3.one * scale;
// 顏色漸變 (Gradient)
float t = Mathf.Clamp01(mass / maxMassForGradient);
sr.color = massColorGradient.Evaluate(t);
尺寸 ∝ 質量^(1/3)
顏色 由 Inspector 設定的
Gradient
控制,質量越大顏色越深/越亮
6. 邊界管理
// BoundaryManager.cs
private void CreateBoundaries() {
float vert = cam.orthographicSize;
float horz = vert * cam.aspect;
CreateWall("Top", new Vector2(0, vert+th/2), new Vector2(horz*2+th*2, th));
// … Bottom / Left / Right …
}
自動在 Orthographic 相機四周生成 2D 靜態牆,防止粒子飛出畫面。
結語
這一輪更新,從底層演算法到使用者互動都做了全面優化:
流暢度:FPS 增加 2–3 倍,GC 幾乎清零
可擴充:模組化架構,易於添加新功能(如不同分裂策略、特效)
體驗:清爽 UI、明確操作流程、不需手動編輯程式碼即可調參
Subscribe to my newsletter
Read articles from 郭俊鑫 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
