当前位置: 首页 > article >正文

Unity 代码优化记录

文档

unity 代码优化分析:https://docs.unity3d.com/Manual/analysis.html

Unity 修复性能问题:https://learn.unity.com/tutorial/fixing-performance-problems-2019-3?courseId=5c87de35edbc2a091bdae346#604586d7edbc2a5b4345d249

实例

具体枚举转Enum类型会有20B的GC

  • 考虑判断原来一致不重复赋值

  • 考虑使用整形存储代替枚举
    在这里插入图片描述


减少使用Enum.TryParse

  • 频繁调用考虑用字典存起来
    在这里插入图片描述

避免频繁调用匿名函数

GC 闭包和匿名方法

  • 减少闭包和匿名函数使用频率。
  • 在这里插入图片描述

在这里插入图片描述


Shader属性用ID代替字符串

Shader.PropertyToID

  • 动画key 和 材质属性考虑初始化先转成对应ID,调用时使用ID。

在这里插入图片描述


减少字符串拼接

Repeated string concatenation

  • 重复的拼接,提前初始化,考虑static,所有组件公用。
    在这里插入图片描述

减少GameObject.Find使用

Find 和 FindObjectOfType
在这里插入图片描述


干掉高耗时,但没有实际影响的物理计算

  • 因为demo中物理引擎只用计算网格相交,不需要重力,受力,速度等参数,所以不需要计算速度约束和位置约束等。考虑增加开关控制。

在这里插入图片描述
在这里插入图片描述


减少查表频率和提前初始化List

  • 常量List避免每次计算new

  • 读表避免频繁调用原始接口重复查找

在这里插入图片描述

在这里插入图片描述


减少 int32.tostring()

  • 避免循环里重复调用相同耗时操作
    在这里插入图片描述

用GPU Instance 减少DrawCall

GPU Instance 深入浅出 知乎

https://docs.unity.cn/cn/current/Manual/GPUInstancing.html

  • demo中血条搞了个类似液体晃动,怪物很多,没用GUP Instance的话,每个怪物都要调一次DrawCall,相同材质和网格的怪物可以合并成一次DrawCall,需要调整shader和C#代码。
shader修改

在这里插入图片描述

C#修改
  • Renderer.GetMaterial() 可以查看源码GraphicesScriptBindings.cppGetAndAssignInstantiatedMaterial
    在这里插入图片描述
结果对比
  • 合批前,每个怪物血液一次DrawCall,合并后所有怪物一次DrawCall。
    在这里插入图片描述

公共只读字段改为静态

公共只读字段,用const或static readonly
在这里插入图片描述

在这里插入图片描述


HashSet代替List循环查找、或判断

在这里插入图片描述


字典等容器复用

为尽量减少容器new带来的gc以及碎片化内存,部分场景可以循环利用容器。

需注意容器复用应尽量在相同使用场景复用,不同使用场景需求的容器大小不同可能造成容器频繁Resize或产生冗余分配。

当然在容量大小确定的情况下使用Native容器作为替代方案也是可以的。
在这里插入图片描述


怪物创建峰波耗时处理

对于短时间内进行大量对象的创建等耗时逻辑,采取的优化方案一般是:分线程处理和分帧处理。

比如短时间内创建大量怪物,采取了分帧处理,限制了每帧最大创建怪物数量。
在这里插入图片描述


字典Key 用int代替String

  • 提前计算String.GetHashCode(),并作为字典key。需要注意可能存在哈希冲突,在分配key时需要处理冲突。
    在这里插入图片描述

用数组代替字典

  • 快个三四倍。

  • GetCom<T>()实体组件原来是传Type类型,底下是Dictionary<Type, XXX>,这个RuntimeType.GetHashCode() 也比较耗时。因为组件数量有限,所以直接分配一个数组,每个组件占一个索引,取得时候用int索引取组件GetCom<T>(int TypeID)

  • 下图红色框。
    在这里插入图片描述


字典字缓存成员变量

  • 频繁取的,但又修改少的,比如怪物移动速度,自己缓存个成员变量。下图绿色框。
    在这里插入图片描述

属性改用成员变量

  • 上图白框。

  • 通常不考虑极端性能时还是推荐用属性。属性编译后实际成了方法,多一层调用堆栈。
    在这里插入图片描述

  • 也可以使用内敛方式[MethodImpl(MethodImplOptions.AggressiveInlining)],把属性代码编译到调用处。
    在这里插入图片描述



http://www.kler.cn/a/543207.html

相关文章:

  • qml ToolBar详解
  • 【动态规划】风扫枯杨,满地堆黄叶 - 9. 完全背包问题
  • 如何评估云原生GenAI应用开发中的安全风险(下)
  • Cursor 编辑器详细介绍与使用
  • 游戏手柄Type-c方案,支持一边充电一边传输数据
  • 【CXX-Qt】1.1 Rust中的QObjects
  • 【c++】shared_ptr是线程安全的吗?
  • fun-transformer学习笔记-Task1——Transformer、Seq2Seq、Encoder-Decoder、Attention之间的关系
  • vivo手机和Windows电脑连接同一个WiFi即可投屏!
  • Spring Cloud 完整引解:优化你的微服务架构
  • GEE批量打开asset权限(anyone can read)
  • YOLOv11融合[AAAI2025]的Mesorch 模型中的高、低频特征提取模块
  • kafka在初始化集群配置当中有哪些重要参数?
  • (定时器,绘制事件,qt简单服务器的搭建)2025.2.11
  • vuedraggable固定某一item的记录
  • 语言大模型基础概念 一(先了解听说过的名词都是什么)
  • 元宵佳节,我的创作纪念日:技术之路的回顾与展望
  • 【多模态大模型】系列1:Transformer Encoder——ViLT、ALBEF、VLMO
  • MVC(Model-View-Controller)framework using Python ,Tkinter and SQLite
  • 机器学习数学基础:22.对称矩阵的对角化
  • LKT4202UGM新一代安全认证加密芯片,守护联网设备和服务安全
  • LeetCode --- 435周赛
  • Java进阶14 TCP日志枚举
  • 如何使用CSS Grid实现两列布局?
  • Tcp_socket
  • 20vue3实战-----使用echarts搭建各种图表