Tổng hợp Optimize NATV
-
🧩Unity Performance Optimization (NATV)
I. Giảm DrawCall
️ Dùng SRP Batcher của URPGom nhiều mesh có cùng shader vào 1 batch drawcall, giúp giảm đáng kể chi phí CPU khi render nhiều object như monster hoặc vật cản.
Bật trong Project Settings → Graphics → SRP Batcher

🧱 Dùng chung Shader / Material / Layer
- Chuyển các vật cản, nơi đứng của monster thành Spine Animation (shader:
Universal Render Pipeline/2D/Spine/Skeleton) - Dùng Layer giống nhau giữa monster và vật cản để SRP gom vào chung batch
- Việc biến
SpriteRendererthànhSpine Animationrất đơn giản – tham khảoCreateSpineAnimForTextureExtensions.cs

Vòng tròn đỏ: Skeleton Animation
🟢 Vòng tròn xanh: Sprite Renderer
🧩 Sprite Renderer – Dùng chung Material & Atlas
Khi vẫn dùng
SpriteRenderer, cần dùng chung material và chung atlas để Unity nhóm các sprite lại thành 1 drawcall.
GPU InstancingDùng cho các object giống nhau:
Ví dụ: cỏ, hiệu ứng vòng tròn tấn công, đá nhỏ, lá rơi, …
→ Giúp giảm drawcall mà vẫn giữ hiệu ứng động.
🧭 Sắp xếp Layer hợp lý
- Layer 1: Mặt đất, cây cỏ, rác, đá sỏi, các vật có thể bị đạp lên.
- Layer 2: Monster, hero, effect, dog, base, obstacle – nơi các vật thể có thể che nhau.

II. Optimize CPU
Giảm đối tượng cần vẽ / tính toánMonster nằm ngoài camera chỉ cần cập nhật logic, không cần render.
→ TrongSkeletonAnimation, bật:
Advanced → Update When Invisible → Only Event Timelines
Loại bỏ Collider / Rigidbody không cần thiếtDùng hệ thống va chạm logic tự tính thay cho vật lý thật:
- Tính khoảng cách giữa tâm hero và monster.
- Nếu nhỏ hơn bán kính kỹ năng → trong phạm vi tấn công.
→ Tham khảo:DetectCollideManager.cs.
III. Optimize Addressables
Tổ chức theo ChapterMỗi chapter là 1 group riêng, chọn Pack Together để Unity build thành 1 bundle duy nhất → gọn nhẹ, dễ load/unload.

Không bỏ Scene vào AddressableScene luôn bị build dạng Pack Separately, dễ bị duplicate asset → tăng size bundle và memory.
🧾 Config chỉ chứa data cơ bản
- Chỉ nên chứa text, number, config JSON.
- Không chứa sprite, texture, sound để tránh trùng atlas.
- Nếu buộc phải có sprite → bỏ tích Include in Build trong atlas và dùng
SpriteAtlasManagerđể load thủ công.

Tham khảo:
SpriteAtlasAddressableLoader.cs
Tài liệu: Unity SpriteAtlasManager
️ Giải phóng tài nguyên đúng cáchMọi handle async của Addressables (
LoadAssetAsync,InstantiateAsync, …)
→ Phải gọiAddressables.Release(handle)khi không dùng nữa.
IV. Optimize Memory
Không tạo object mới mỗi frameKhông
new string,new List,new Dictionary... trongUpdate→ gây GC Alloc liên tục.
→ Dùng biến cache hoặcList.Clear()để tái sử dụng.
🧹 Dọn dẹp bộ nhớ
Khi đổi scene, gọi:
Addressables.ReleaseUnusedAssets(); Resources.UnloadUnusedAssets();Có thể thêm
GC.Collect()trong màn hình loading để thu hồi managed memory.
🧱 Giảm phân mảnh bộ nhớ
- Dùng
List,Queue,Stack,Dictionarycó capacity cố định. - Tính trước kích thước hợp lý ngay từ đầu để tránh
reallocate. - Tham khảo code gốc của .NET
List<T>:
List.cs#L198 - Dùng Object Pooling cho object tạo–hủy thường xuyên (đạn, hiệu ứng, popup...).
V. Optimize Spine Animation
- Gom tất cả monster cùng chapter vào 1 atlas duy nhất
→ ví dụ:Chapter_01_Monsters.atlas,Chapter_02_Monsters.atlas. - Nếu vùng sprite là hình lồi, cắt lồi để giảm vertices/triangle.
- Bật Triangulate Low Detail hoặc giảm precision vùng mesh.
- Tránh sprite có alpha phức tạp hoặc chi tiết biên thừa.
- Giảm bone, attachment, slot không cần thiết.
- Gộp nhiều attachment tĩnh thành 1 sprite duy nhất.
- Xóa bone test, placeholder, slot không render.
- Animation đơn giản (vd: idle) chỉ cần 2 keyframe đầu/cuối (Spine tự nội suy).
- Xóa keyframe dư và animation không dùng runtime.
VI. Optimize Texture
- Dùng ASTC thay vì RGBA32 để giảm kích thước build và RAM.
- Dùng ASTC 10×10 hoặc 12×12 nếu chất lượng hình ảnh vẫn ổn.
- Gom sprite hợp lý vào atlas để giảm texture switch.
VII. Optimize UIToolkit
- Dùng
usageHints:
Giúp Unity xác định cách tối ưu layout và render cho UI element. - Giảm thay đổi transform:
Không thay đổiposition,rotation,scalethường xuyên — vì sẽ rebuild layout gây tốn CPU.
VIII. Optimize Âm Thanh
- Decompress On Load:
Cho âm thanh phát liên tục (bắn, hit, bước chân). - Streaming:
Cho âm thanh dài (nhạc nền, voice, cutscene). - Compress In Memory:
Cho âm thanh ngắn, ít khi phát (click UI, hiệu ứng nhỏ). - Load In Background:
Dùng cho các âm thanh không yêu cầu độ chính xác cao để không chặn luồng chính.
IX. Optimize Script
-
Cache các giá trị dùng nhiều:
Animator.StringToHash(trigger animation).LayerMask.GetMask,LayerMask.NameToLayer.Camera.main(vì gọi lại sẽFindGameObjectWithTag).
-
Tạo collection có capacity cụ thể:
new List<int>(64)hoặcnew Dictionary<string, int>(32)để tránh mở rộng mảng. -
Dùng HashSet thay List:
Nếu chỉ cần kiểm traContains,Add,Remove– tốc độ nhanh hơn nhiều. -
Local Function:
Đặt ở lớp ngoài cùng, truyền tham số rõ ràng để tránh GC capture closure.
- Xoá các hàm Update() hoặc FixedUpdate() nếu không dùng đến
- Chuyển các vật cản, nơi đứng của monster thành Spine Animation (shader:
-
Addressables.ReleaseUnusedAssets(); Resources.UnloadUnusedAssets(); GC.Collect()Những đoạn code ở trên này có thể gây performance, chỉ nên sử dụng nó vào một số thời điểm nhất định như chuyển scene, không nên sử dụng thường xuyên ví dụ như bỏ vào Update()
- Optimize CPU cho UIToolkit:
- Tránh sử dụng long hierarchy (một object bao gồm nhìu con lồng nhau trong đấy). Vì UIToolkit sẽ truy vết tới con cuối cùng và ngược lại phần root khi có sự thay đổi layout
- GPU Instancing:
- Dùng cho các object giống nhau về material, mesh. Và thông thường thì sẽ không chuyển động, hoặc chuyển động theo quy luật giống nhau
- Sprite Renderer – Dùng chung Material & Atlas:
- Dùng chung material, nếu không gán material vào SpriteRenderer thì Unity sẽ fallback về Sprite/Default mặc định.
- Dùng chung atlas và dùng chung Sorting Layer.
-