NodeBB

    • Login
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups

    Tổng hợp Optimize NATV

    Developer Discussion
    2
    3
    9
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • C
      changx last edited by changx

      🧩Unity Performance Optimization (NATV)


      I. Giảm DrawCall

      ⚙️ Dùng SRP Batcher của URP

      Gom 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

      SRP Batcher Example


      🧱 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 SpriteRenderer thành Spine Animation rất đơn giản – tham khảo CreateSpineAnimForTextureExtensions.cs

      Skeleton vs Sprite Renderer

      🔴 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.

      Sprite Renderer Atlas Example


      🌿 GPU Instancing

      Dù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.

      Layer Setup Example


      II. Optimize CPU

      🔄 Giảm đối tượng cần vẽ / tính toán

      Monster nằm ngoài camera chỉ cần cập nhật logic, không cần render.
      → Trong SkeletonAnimation, bật:
      Advanced → Update When Invisible → Only Event Timelines

      Update When Invisible Setting


      ⚡ Loại bỏ Collider / Rigidbody không cần thiết

      Dù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 Chapter

      Mỗ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.

      Addressable Group Setup


      🚫 Không bỏ Scene vào Addressable

      Scene 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.

      Sprite Atlas Include Example

      Tham khảo: SpriteAtlasAddressableLoader.cs
      Tài liệu: Unity SpriteAtlasManager


      ♻️ Giải phóng tài nguyên đúng cách

      Mọi handle async của Addressables (LoadAssetAsync, InstantiateAsync, …)
      → Phải gọi Addressables.Release(handle) khi không dùng nữa.


      IV. Optimize Memory

      🚫 Không tạo object mới mỗi frame

      Không new string, new List, new Dictionary... trong Update → gây GC Alloc liên tục.
      → Dùng biến cache hoặc List.Clear() để tái sử dụng.

      Memory GC Example


      🧹 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, Dictionary có 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 đổi position, rotation, scale thườ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ặc new Dictionary<string, int>(32) để tránh mở rộng mảng.

      • Dùng HashSet thay List:
        Nếu chỉ cần kiểm tra Contains, 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

      1 Reply Last reply Reply Quote 0
      • T
        thongtruong last edited by thongtruong

        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()

        1. 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
        1. 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
        1. 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.
        1 Reply Last reply Reply Quote 1
        • C
          changx last edited by

          https://learn.unity.com/tutorial/fixing-performance-problems-2019-3

          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Powered by NodeBB | Contributors