Unity性能优化篇(十四) 其他优化细节以及UPR优化分析器

代码优化:
1. 使用AssetBundle作为资源加载方案。
而且经常一起使用的资源可以打在同一个AssetBundle包中。尽量避免同一个资源被打包进多个AB包中。压缩方式尽量使用LZ4,少用或不要用LZMA的压缩方式。如果确定后续开发不会升级Unity版本,则可以尝试启用打包选项BuildAssetBundleOption.DisableWriteType,这样TypeTree信息不会被打到AB包中,可以极大减小包体大小以及运行加载时的内存开销。
2. 使用AssetBundle或者Addressables加载的资源,如果不使用,要记得卸载它们,否则会造成内存泄漏。
不用的资源要释放掉,不用的引用类型的变量也要赋值为null,不要让它们一直占着内存中。
3. 加载资源时尽量使用异步加载。
4. 频繁创建和销毁对象,可以使用对象池。
5. 切换场景时,旧的场景要释放掉,不用的资源也可以考虑释放掉,也可以考虑用System.GC.Collect来进行一次垃圾回收。
6. 锁定游戏的帧率 。帧率为30,游戏会明显卡顿,但是对于手游来说,消耗手机的电量比较少。帧率为45,游戏有一点点卡,但还凑合,消耗电量中等。帧率为60,游戏很流畅,但消耗手机的电量会比较多。可以用Application.targetFrameRate来锁定帧率,也可以用UnityEngine.Rendering命名空间中的OnDemandRendering.renderFrameInterval来锁定帧率。
7.尽量少用foreach语句,可以改为for语句。因为每次使用foreach语句会造成微量的内存垃圾。
8.要判断GameObject型对象.tag是不是某个标签,使用GameObject型对象.CompareTag方法会更高效。
9. 尽量少用GameObject.Find方法和Object.FindObjectOfType方法来查找游戏对象,可以提前把要查找的游戏对象存储在变量、列表、字典等容器中,方便查找。也可以用GameObject.FindGameObjectWithTag方法来查找游戏对象。
10. 在UI显示字符串的时候,如果一些内容是固定的,我们可以把它拆分开来,这样可以减少使用+号来拼接的次数,减少内存垃圾的产生。例如“杀敌数:999”,其中“杀敌数:”是固定的,冒号后面的数字才是会变的,那么我们可以用两个Text组件分别记录它们,改变的时候只改变冒号后面的数字。
11.频繁对字符串赋新的值,或者频繁拼接字符串的时候,可以使用StringBuilder代替string
12. 如果要频繁操作某脚本,不要每次都用GetComponent方法来获取这些脚本。可以用一个变量存储起获得的这个脚本,之后要访问它,就直接访问这个变量即可。也可以考虑在生命周期方法Awake或者Start中声明变量来存储,之后访问这个变量即可。
13.尽量少用正则表达式。虽然正则表达式的形式看上去比较简便,但是使用它会造成一定的性能消耗,且会产生内存垃圾。
14.尽量少用LINQ语法,因为每次使用LINQ都会产生一定量的内存垃圾。
15.尽量少用Camera.main来访问主摄像机,因为每次访问它,实际上Unity都是从场景中查找它的。可以声明一个变量存储它,在生命周期方法Awake或Start中获取主摄像机的应用。
16.在Animator、Shader中使用Get方法和Set方法时,不传入字符串作为参数,而是传入哈希值。例如Animator组件可以使用Animator.StringToHash方法获得指定字符串的哈希值,再把它作为参数传入Animator组件的Get方法或Set方法中进行使用。例如Shader,则可以用Shader.PropertyToID方法来获取指定属性的ID
17.使用非分配物理API。例如使用Physics.RaycastNonAlloc方法代替Physics.RaycastAll方法,使用Physics.SphereCastNonAlloc方法代替Physics.SphereCastAll方法,以此类推。Physics2D类也有类似的方法。
18.一般情况下,整数的数学运算比浮点数的数学运算效率高,浮点数的数学运算比矢量的数学运算效率高。可以灵活运用数学的加法交换律、加法结合律、乘法交换律、乘法结合律,在保证结果不变的前提下,调整运算顺序,减少浮点数的数学运算和矢量的数学运算。
19.使用高效的算法进行计算
20.每次执行Debug.Log来打印信息会消耗极少量的性能,如果要在游戏正式发布之后不执行某些Debug.Log的语句,但又不想把这些代码删掉,则可以使用宏来禁止在游戏正式发布之后执行Deubg.Log的语句。例如使用#if语句或者Conditional特性。
21.尽量减少在生命周期方法Update、FixedUpdate、LateUpdate中的逻辑。其中有些不需要频繁执行的逻辑,可以使用协程或者Invoke方法,每隔指定的秒数执行一次或每隔指定的帧数执行一次。
22. 尽量避免频繁的装箱拆箱操作。也可以使用泛型,这样就能避免装箱拆箱。但是要注意,Lua热更新对泛型的支持不太好。
23.如果物体身上添加了刚体组件,则尽量用刚体组件的方法来移动它,而不是用Transform类的方法来移动它。
24.如果物体身上添加了CharacterController组件,则尽量用CharacterController组件的方法来移动它,而不是用Transform类的方法来移动它。同理,如果物体身上添加了刚体组件,则应尽量用刚体组件的方法来移动它,而不是用Transform类的方法来移动它。
25.应尽量避免DontDestroyOnLoad中加载的资源过多,因为它在切换场景的时候不会被释放,声明的变量以及加载的资源会一直占用着内存。我们可以考虑把一些资源不用的资源释放掉,需要的时候再加载它。
26.不使用组件可以删掉,这样可以节省一些内存。常见的有AudioSource组件、Animator组件、Animation组件等,如果它们不需要使用,则可以删掉。
27.写一个类继承AssetPostProcessor,然后定义里面特定的方法,以此来自动设置资源导入Unity之后的属性。
28.尽量避免闭包。因为闭包会产生额外的内存开销。

可以使用Unity UPR对整个项目进行性能分析,找出问题后,再手动优化它们。
Unity UPR网址:https://upr.unity.cn/instructions/desktop
其中Unity UPR中的Asset Checker能对本地的整个Unity项目进行性能分析,帮助我们找出问题。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/595793.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++不知算法系列之滑动指针

公众号:编程驿站 1. 前言 双指针搜索算法,常见的有左右双指针;快慢双指针;先后双指针以及多指针……其中还包括一类滑动指针。滑动指针也称为滑动窗口指针,其搜索实现即有灵性又透着优雅。 本文通过几个案例聊聊滑动…

【Java EE】初识Spring Web MVC

文章目录 🌴什么是Spring Web MVC?🌸什么是Servlet呢? 🌲MVC 定义🌸再理解Spring MVC 🌳如何学习Spring MVC呢?⭕总结 🌴什么是Spring Web MVC? Spring Web MVC 是基于…

Github 2024-04-05Java开源项目日报Top9

根据Github Trendings的统计,今日(2024-04-05统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目9TypeScript项目1OpenAPI 生成器:基于规范自动生成API工具 创建周期:2155 天开发语言:Java协议类型:Apache License 2.0Star数量:1…

二叉树oj题(1)

1.检查两棵树是否相同 解题思路: 1.两棵树都为空,return true 2.一个为空,一个不为空,return false 3.节点不为空,但值不相同,return false 以上都是特殊情况,如果没有这些情况,就…

NoSQL概述

NoSQL概述 目录 一、为什么用NoSQL 二、什么是NoSQL 三、经典应用分析 四、N o S Q L 数 据 模 型 简 介 五、NoSQL四大分类 六、CAP BASE 一、为什么用NoSQL 1、单机MySQL的美好年代 在90年代,一个网站的访问量一般不大,用单个数据库完全可以轻松应…

理解Go语言中的并发和并行

即使有多年的并发编程经验,有些开发人员也可能无法清楚地理解并发(concurrency)和并行(parallelism)之间的区别。下面我们以一个真实的例子来说明:一家咖啡店。 在这家咖啡店中,一名服务员负责接收订单并使用一台咖啡机进行准备。顾客下订单,然后等待他们的咖啡。 …

99%的人不知道,Oracle resetlogs强制开库需要推进SCN?

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…

蓝桥杯 十一届C++A组 字符排序 21分(运行超时)

思路: 1. 此题考查的冒泡排序中的交换次数,其实就是考察当前数与后面的逆序对个数问题。而为了最大利用位数,应当使每一位都不小于后面的字符,否则会造成一次逆序对的浪费(贪心,为了使总位数最少&#xff…

贪心算法|55.跳跃游戏

力扣题目链接 class Solution { public:bool canJump(vector<int>& nums) {int cover 0;if (nums.size() 1) return true; // 只有一个元素&#xff0c;就是能达到for (int i 0; i < cover; i) { // 注意这里是小于等于covercover max(i nums[i], cover);if…

了解IP地址的基本概念和修改步骤

在数字化时代&#xff0c;IP地址作为网络设备的唯一标识&#xff0c;其重要性不言而喻。无论是为了提升网络性能&#xff0c;还是出于隐私保护的需求&#xff0c;修改IP地址都是网络使用者可能遇到的操作。虎观代理将详细介绍如何修改IP地址&#xff0c;并探讨在修改过程中需要…

Codeforces Round 832 (Div. 2) D. Yet Another Problem

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5; c…

python_3

文章目录 题目运行结果模式A模式B模式C模式D 题目 mode input("请选择模式:") n int(input("请输入数字:"))if mode "A" or mode "a":# 模式A n:输入的层数 i:当前的层数# 每行数字循环次数 ifor i in range(1, n 1):for j in r…