mcpField
U
unity-performance

unity-performance

github.com/josiahsiegel开发59100 次安装19 周前更新
代码仓库

关于 unity-performance

面向 Unity 游戏开发者的性能分析与优化参考,涵盖 CPU、GPU、内存、渲染和平台差异,并提供反复分析与对比的工作流程。

主要功能

  1. 01Unity 性能分析流程
  2. 02CPU 与垃圾回收优化
  3. 03GPU 与渲染优化技巧
  4. 04内存与资源加载指导
  5. 05平台性能注意事项

适用场景

  1. 01排查目标设备上的帧耗时瓶颈
  2. 02减少游戏运行时分配和对象创建
  3. 03优化复杂场景的渲染
  4. 04管理不同平台的内存与资源加载

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill unity-performance

安装后在 Claude Code 中输入/unity-performance确认已加载。

详细介绍

Unity 性能优化

概述

采用系统化方法分析和优化 Unity 游戏。涵盖性能分析工具、CPU/GPU 优化、内存管理、渲染优化和平台特定注意事项。

性能分析工具

工具显示内容使用时机
Unity Profiler每帧的 CPU、GPU、内存、音频和物理数据处理任何性能问题时的第一站
Frame Debugger绘制调用细分、着色器/材质状态渲染瓶颈
Memory Profiler堆快照、纹理/网格内存内存泄漏、内存膨胀
Profile Analyzer对比采集数据、统计分析优化前后对比
Physics Debugger碰撞体可视化、接触点物理性能
Profiler 工作流
  1. 启用 Development Build 和 Autoconnect Profiler 进行构建
  2. 在目标设备上进行性能分析(不要在 Editor 中进行——Editor 的额外开销会扭曲结果)
  3. 确定瓶颈类别:受 CPU 限制、受 GPU 限制,或内存压力
  4. 深入分析导致问题的具体系统
  5. 优化后重新进行性能分析并比较
读取 Profiler
If frame time > 16.6ms (60 FPS target):
  CPU timeline > GPU timeline -> CPU-bound
  GPU timeline > CPU timeline -> GPU-bound
  GC.Alloc column shows per-frame allocations -> GC pressure

留意尖峰(单帧异常)与持续高耗时(基准负载过重)的区别。

CPU 优化

减少每帧分配(GC)
反模式修复方法
在 Update 中使用 string + string使用 StringBuilder 或缓存结果
每帧执行 new List<T>()只分配一次,然后用 Clear() 清空并复用
在热点路径中使用 LINQ改用手动循环
每帧调用 GetComponent<T>()在 Awake/Start 中缓存
每帧调用 GameObject.Find()缓存引用或使用事件
对非泛型集合使用 foreach使用 for 循环或泛型集合
SendMessage() / BroadcastMessage()使用直接调用、事件或接口
装箱值类型使用泛型集合,避免转换为 object
对象池
public class ObjectPool<T> where T : Component
{
    readonly Queue<T> _pool = new();
    readonly T _prefab;
    readonly Transform _parent;

    public ObjectPool(T prefab, int preWarm, Transform parent = null)
    {
        _prefab = prefab;
        _parent = parent;
        for (int i = 0; i < preWarm; i++)
            _pool.Enqueue(CreateInstance());
    }

    public T Get(Vector3 position, Quaternion rotation)
    {
        var obj = _pool.Count > 0 ? _pool.Dequeue() : CreateInstance();
        obj.transform.SetPositionAndRotation(position, rotation);
        obj.gameObject.SetActive(true);
        return obj;
    }

    public void Return(T obj)
    {
        obj.gameObject.SetActive(false);
        _pool.Enqueue(obj);
    }

    T CreateInstance()
    {
        var obj = Object.Instantiate(_prefab, _parent);
        obj.gameObject.SetActive(false);
        return obj;
    }
}

对频繁实例化/销毁的对象使用对象池,例如子弹、粒子、敌人和 UI 元素。Unity 2021+ 还内置了 UnityEngine.Pool.ObjectPool<T>。

Update 优化
技术说明
错开更新不要每帧更新所有 AI;使用分组轮询
基于距离的 LOD降低远处对象的更新频率
事件驱动尽可能用事件替代轮询
禁用未使用的脚本对屏幕外组件设置 enabled = false
使用 InvokeRepeating用于定期检查(比让协程挂起更省开销)

GPU / 渲染优化

减少绘制调用
技术方法节省效果
静态合批将不移动的对象标记为 Static在构建时合并网格
动态合批自动处理小型网格(<300 顶点)仅适用于 URP/Built-in
GPU 实例化为重复对象启用材质实例化树木、草地、岩石
SRP BatcherURP/HDRP 中默认启用减少 SetPass 调用
纹理图集将纹理合并到图集中减少材质切换
网格合并在运行时使用 CombineMeshes()自定义合批
LOD(细节层次)
LOD Group Setup:
  LOD 0 (0-30%):  Full-detail mesh (5000 tris)
  LOD 1 (30-60%): Medium mesh (2000 tris)
  LOD 2 (60-90%): Low mesh (500 tris)
  Culled (90%+):  Not rendered

网格可以使用 LOD,同时也要减少远处对象的脚本复杂度、粒子数量和物理计算。

遮挡剔除

为室内或复杂场景烘焙遮挡数据。将大型静态遮挡物(墙壁、地板)标记为遮挡物。根据场景规模配置单元格大小。使用 Occlusion Culling 窗口进行可视化和测试。

着色器优化
问题解决方案
片元着色器过于复杂减少纹理采样次数,简化数学运算
过度绘制尽量减少透明对象,尽可能使用不透明对象
变体过多在构建设置中剔除未使用的着色器变体
后处理开销过大在移动端禁用效果,改用开销更低的替代方案

内存管理

常见内存问题
问题症状修复方法
纹理臃肿内存占用高,加载时间长压缩纹理,并按平台降低最大尺寸
已卸载的场景仍持有引用内存随时间不断增长场景切换后使用 Resources.UnloadUnusedAssets()
未释放 Addressables资源包仍留在内存中调用 Addressables.Release(handle)
音频剪辑未压缩内存占用巨大音乐使用内存压缩;音效在加载时解压
网格启用了读/写每个网格的内存占用翻倍如果运行时不需要读/写,则将其禁用
各平台的纹理压缩
平台格式备注
PC/ConsoleBC7 (DXT)质量与大小的比率最佳
AndroidASTC 6x6通用格式,质量可调
iOSASTC 6x6与 Android 相同
WebGLETC2 / DXT取决于目标 GPU

在纹理导入设置中使用“Override for [Platform]”。将纹理最大尺寸设为所需的最小值(UI 图标为 512,道具为 1024,主视觉资源为 2048)。

平台特定注意事项

平台主要限制
Mobile热降频、内存有限、电池消耗、受填充率限制
WebGL不支持线程(Unity 6 之前),下载体积大,不支持计算着色器
Console认证要求、硬件固定、内存预算
VR/XR最低 72-90 FPS、立体渲染开销、帧率下降会导致晕动症

Addressables 和资源加载

使用 Addressables 异步加载资源,避免加载时卡顿:

// Preload during loading screen
var handle = Addressables.LoadAssetAsync<GameObject>("enemy_boss");
await handle;

// Release when done
Addressables.Release(handle);

使用 Addressable 组控制资源包粒度。将不常使用的资源标记为远程/按需加载。使用 Addressables Event Viewer 分析资源包内存占用。

快速优化检查清单

  • 在目标设备上分析性能,而不是在 Editor 中分析
  • 游戏逻辑代码中每帧 GC 分配为零
  • 为所有频繁生成的对象使用对象池
  • 为静态对象启用静态批处理
  • 为所有会在不同距离下显示的 3D 模型设置 LOD 组
  • 按平台压缩纹理,并设置合适的最大尺寸
  • 禁用运行时不会修改的网格和纹理的读/写
  • 为音频剪辑设置合适的压缩选项
  • 为室内/复杂场景烘焙遮挡剔除
  • 在构建设置中剥离着色器变体

更多资源

参考文件
  • references/profiling-deep-dive.md -- Profiler 高级用法、内存分析器快照、逐帧分析、自定义 Profiler 标记、自动化性能测试、构建体积分析、ECS/DOTS 性能模式

评论

支持 Markdown