网站接入商是什么意思,700个吉祥公司名字,12306网站多钱做的,中国企业500强厉害吗1.避免频繁创建临时对象
错误写法#xff1a;obj.transform.position pos;这种写法会在Lua中频繁返回transform对象导致gc正确写法#xff1a;创建一个静态方法来设置位置#xff0c;例如 class LuaUtil { static void SetPos(GameObject obj, float x, float y, float z)…1.避免频繁创建临时对象
错误写法obj.transform.position pos;这种写法会在Lua中频繁返回transform对象导致gc正确写法创建一个静态方法来设置位置例如 class LuaUtil { static void SetPos(GameObject obj, float x, float y, float z) { obj.transform.position new Vector3(x, y, z); } } Lua中调用LuaUtil.SetPos(obj, float x, float y, float z);
2.使用泛型必须生成对应类型的wrap文件
错误写法泛型容器直接使用正确写法_GT(typeof(Dictionaryint, long)然后生成对应的wrap文件Lua调用避免产生GC
3.使用C#容器如果知道大概的容量尽量指定初始化大小避免自动扩容产生的GC例如List、Dictionary、Array
错误写法 Dictionaryulong, int buffTableIndexMap new Dictionaryulong, int(); List list new List(); for (int i 0; i 1000; i) { list.Add(i); }正确写法Dictionaryulong, int buffTableIndexMap new Dictionaryulong, int(1000); List list new List(1001); for (int i 0; i 1000; i) { list.Add(i); }
4.注意非托管类型的手动释放
错误写法 Marshal.AllocHGlobal没有调用Marshal.FreeHGlobal继承自IDisable接口的对象没有手动调用dispose方法 正确写法 调用手动释放内存的接口方法
5.注意循环内部
Unity携程 错误写法大量的使用Coroutine正确写法使用Update自己管理状态 携程等待 错误写法大量使用yield return new WaitForEndOfFrame();或者new WaitForSeconds(3f)或者new WaitForFixedUpdate()等正确写法保存一个new等待对象重复使用 New 对象 错误写法循环内部不断new 对象正确写法使用对象池循环使用 频繁显/隐 SetActive 错误写法频繁调用正确写法可以移到相机视野外或者设置透明度 频繁操作组件方法/属性 GetComponentAddComponentFind/FindWithTagGetTagCamera.main 内部使用的FindGameObjectsWithTag()Object.name错误写法频繁调用 function Update() local cube CS.UnityEngine.GameObject.Find(“Cube”) cube.transform:Rotate(CS.UnityEngine.Vector3(0, 90, 0) * CS.UnityEngine.Time.deltaTime) end void Update() { Camera.main.orthographicSize //Some operation with camera }正确写法第一次获取之后缓存之后复用 – 正确写法在Start中获取组件并缓存 function Start() self.cube UnityEngine.GameObject.Find(“Cube”).transform end
– 在Update中使用缓存的组件 function Update() self.cube:Rotate(UnityEngine.Vector3(0, 90, 0) * UnityEngine.Time.deltaTime) end private Camera cam; void Start() { cam Camera.main; } void Update() { cam.orthographicSize; }
SendMessage 错误写法直接使用SendMessage方法内部调用了反射正确写法使用事件系统
6.字符串处理
大量字符串处理 错误写法大量字符串拼接、切割 void Update() { text.text Player name has score score.toString(); }正确写法尽量减少这种使用场景用stringbuilder或者用ZString替代(原理基于Span动态数组实现的0gc字符串方案) void Start() { text GetComponent (); builder new StringBuilder(50); } void Update() { builder.Length 0; builder.Append(Player “); builder.Append(name); builder.Append(” has score ); builder.Append(score); text.text builder.ToString(); } 大量使用正则表达式使用linq查询 错误写法 var query from item in myList where item.SomeProperty someValue select item linq会分配临时空间正确写法使用for循环遍历
7.C#、Lua数据传递交互
错误写法把字符串当key传入例如 luaState.Push(MBuffMgr.UID_str); luaState.Push(buff.UID); 或者 theSubTable[MBuffMgr.UID_str] buff.UID;正确写法使用数组而不是哈希表例如 theSubTable[1] buff.UID 或者使用枚举 theSubTable[(int)EBuffAttr.UID] buff.UID
8.物理接口的使用 使用物理接口例如Physics.Raycast、Physics.SphereCast、Physics.BoxCast和Physics.CapsuleCast等方法
错误写法不注意检测长度和检测layer正确写法正确评估检测长度和设置必要的检测layer减少不必要的物理计算量
9.同步异步接口使用 例如资源加载接口
不推荐写法使用同步接口推荐写法: 使用异步接口
10.分帧加载
错误写法 length比较大 for (int i 0; i prefabs.Length; i) { Instantiate(prefabs[i], parent); }正确写法 IEnumerator LoadPrefabs() { var waitForOneSecond new WaitForSeconds(1); for (int i 0; i prefabs.Length; i) { yield return waitForOneSecond; // 每帧延迟1秒可以根据需要调整 Instantiate(prefabs[i], parent); } }
11.注意Lua与C#交互传递Unity特有的值类型 Lua调用C#函数时涉及到参数的传递和返回值的处理这些操作都会产生性能开销。特别是当涉及到Unity特有的值类型如Vector3、Quaternion等时性能消耗更大因为需要进行类型转换 错误写法 function Update() local cube CS.UnityEngine.GameObject.Find(“Cube”) cube.transform.rotation CS.UnityEngine.Quaternion.Euler(0, 45 * CS.UnityEngine.Time.deltaTime, 0) end 正确写法 function Start() self.cubeTransform CS.UnityEngine.GameObject.Find(“Cube”).transform end
– 在Update中使用缓存的组件 function Update() LuaUtil.SetRotation(self.cubeTransform, 0, 45 * UnityEngine.Time.deltaTime, 0) end C#的封装方法 public static SetRotation(transform, float x, float y, float z)
12.lua判空的写法 判空防止误写成
不推荐写法if theMap nil then建议写法if nil theMap then
13.代码规范 建议按照约定熟成的方式最大的收益方便搜索
驼峰命名左右空格枚举类型使用E开头 空格不要多也不要少 错误写法table[i 1] 1 正确写法table[i 1] 1
14.不要写立即数 影响代码阅读和统一修改
错误写法 table[1] 1 – 前面的1代表索引1后面的1表示刷新标记正确写法 FlagIndex 1 RefreshFlag 1 table[FlagIndex] RefresFlag
15.注意频繁调用函数参数量的控制
推荐写法 最好不要超过4个参数
16.优先使用static函数导出减少使用成员方法导出 道理大家都懂
17.控制成员方法导出数量 不必要导出的函数用[NoToLuaAttribute]标记减少lua虚拟机注册的函数数量
正确写法 [NoToLuaAttribute] public void InsertBuffObj(MBuff buff, bool isTarget) {
}
18.使用哈希值而不是字符串 针对Animator、Material或Shader属性进行内部寻址推荐采用哈希的写法例如Animator.StringToHash、Shader.PropertyToID项目中写字符串都要谨慎能不写就不写
错误写法 void Start() { anim GetComponent(); anim.SetFloat(“Speed”, 1.0f); }正确写法 void Start() { anim GetComponent(); // 将字符串参数名转换为哈希值 int speedHash Animator.StringToHash(“Speed”); // 然后可以使用这个哈希值来设置参数值 anim.SetFloat(speedHash, 1.0f); }
19.命名规范
不推荐使用2、4命名可以用To、For不要使用拼音用最容易想到的单词
20.同时设置坐标和旋转
推荐写法 Transform.SetPositionAndRotation GameObject.Instantiate(prefab, parent, position, rotation)不推荐写法 分开设置好几次属性
21.物理检测使用NoAlloc接口
错误写法 var layerMask ~0; if (Physics.Raycast(transform.position, transform.forward, m_Results, Mathf.Infinity, layerMask) 0) {
} Physics2D. CircleCast();
正确写法 var layerMask ~0; if (Physics.RaycastNonAlloc(transform.position, transform.forward, m_Results, Mathf.Infinity, layerMask) 0) {
} Physics2D. CircleCastNonAlloc();
22.数据配置
表格数据配置不要使用拼接的方式在运行时分割数据存储不要采用json、xml等配置推荐使用二进制或者scriptable object
23.不要出现空的Unity事件
错误写法 void Update() {
}
24.尽可能减少每帧运行的代码 考虑代码是否必要每帧执行如果不需要的话可以控制调用频率
推荐写法 private int interval 3;
void Update() if (Time.frameCount % interval 0) Function();
25.避免初始化函数处理太复杂的逻辑 例如Awake、Start、OnEnable中处理复杂的逻辑增加启动加载时间
26.调用统一的日志接口 调用统一接口方便宏定义开关管理
错误写法 print(“这是一条日志”) Debug.log(“这是一条日志”)正确写法 LogManager.Print(“这是一条日志”)
27.避免运行时添加组件 在运行时AddComponent需要一些开销因为要检查是否重复组件或者需要其他依赖组件
推荐做法 采用预制件
28.vector距离判断 如果只是距离判断推荐使用
不推荐写法 Vector3.Magnitude(vec)推荐写法 Vector3.SqrMagnitude(vec)
29.向量乘 向量乘需要耗时多一点尽可能少的做向量运算
不推荐写法 Vector3 c 3 * Vector3.one * 2;推荐写法 Vector3 c 3 * 2 * Vector3.one;
30.shader数据精度 能用小的就不用大的 Float(32bit) (位置与纹理坐标信息) Half(16bit)纹理坐标与颜色信息 Fixed(11bit)颜色信息(SRP下不支持)
31.除法转换成乘倒数 频繁的做除法运算可以改成乘以倒数属于指令集优化硬件上乘以倒数比除执行效率高
不推荐写法 var res a / b; Var res a / 5f;推荐写法 var res a * (1 / b); var res a * 0.2f; 除法运算性能开销时间是乘法的100倍(官方说法)
32.双重循环 不得已要双重循环大循环在内部
不推荐写法 for (int i 0; i numTests; i) { for (int j 0; j 2; j) { int k i * j; } }推荐写法 for (int i 0; i 2; i) { for (int j 0; j numTests; j) { int k i * j; } } [图片]
33.string操作 多次字符串操作推荐使用stringbuilder避免new string产生gc如果stringbuilder能确定长度最好先指定长度也可以用ZString库
34.struct替代class 能用struct的就用struct实在用不了再考虑class
35.系统自带默认值 例如Quaternion,Vector3等默认值全局静态只读变量全局只有一个减少一次new的操作
不推荐写法 Vector3 v3 new Vector3(0, 0, 0);推荐写法 Vector3 v3 Vector3.zero;
37.避免装拆箱 装箱值类型-引用类型 int value 11; object obj value; 拆箱引用类型-值类型 object obj 42; int value (int)obj;
不推荐写法 循环内部产生拆箱、装箱的写法
38.正确使用对应的数据结构 大量的数据查询操作
错误写法 for(int i0; i1000; i) { if(list.Contains(i)) { //todo } } 还有不要用for循环遍历查找luatable的数组表(数据量比较大)正确写法 用HashSet结构或者lua哈希表
39.循环修改值
错误写法 foreach(var item in array) { if(item.id xxx) { item.xxx xxx } }正确写法 for(int i 0;i array.count; i) { if(array[i].id xxx) { array[i].xxx xxx } }
40.循环删除 倒序删除
推荐写法 // 假设有一个List List myList new List { 1, 2, 3, 4, 5 };
// 倒序删除所有偶数元素 for (int i myList.Count - 1; i 0; i–) { if (myList[i] % 2 0) { myList.RemoveAt(i); } }
不推荐写法 正序删除
41.获取组件 在Unity中GetComponent方法有三种重载方式GetComponent()、GetComponent(Type type)和GetComponent(string type)。根据搜索结果推荐使用泛型方式GetComponent()
推荐写法 GetComponent() 效率最高耗时最少
42.跳过当前帧
不推荐写法 yield return new WaitForFrame();推荐写法 yield return null; yield return 0;
43.代码编写原则
推荐原则 尽早返回如果函数在执行过程中遇到可以立即确定结果的条件应立即返回而不是继续执行更多代码才返回避免深层嵌套减少代码嵌套层数可以提取函数使用循环控制语句等方式来实现警惕递归调用单一出口点尽量让函数只有一个返回点减少代码复杂性使得函数执行流程更加清晰函数职责单一确保一个函数只做一件事情减少函数内部复杂度和耦合度使得函数更容易理解和维护功能通过若干单一函数组装使用断言检测函数参数的合法有效性如果不合法则立即抛出异常或返回
44.避免单帧大循环逻辑处理 CPU瞬时压力过大造成Big Jank
不推荐写法 for(int i 0;i 100;i ) {
}
推荐策略 分帧处理算法处理例如二叉树、四叉树、AOI等算法策略
45.碰撞检测
不推荐写法 collider碰撞检测推荐写法 vector距离检测
46.异步编程
不推荐写法 void Start() { StartCoroutine(DelayedAction()); }
// 协程方法延迟2秒后执行 IEnumerator DelayedAction() { yield return new WaitForSeconds(2.0f); // 等待2秒 Debug.Log(“Delayed action executed after 2 seconds”); }
推荐写法 async void Start() { await Task.Delay(2000); }
47.lua代码变量
错误写法 都写成全局变量
48.扩展原方法/类 扩展模板代码方法或者引擎内部方法
错误写法 生成模板代码直接生成class正确写法 生成partial class的模板代码方法以便提供扩展能力使用扩展方法
49.谨慎频繁调用强制垃圾回收
不推荐写法 定期执行Resources.UnUsedAssets() 或者lua的collectgarbage(“collect”)推荐写法 资源采用引用计数管理和释放不需要频繁粗暴调用Resources.UnUsedAssets()会造成很大的帧率jank手动在合适的时机调用gc方法
50.向量浮点数运算
不推荐写法 Vector3 pos1 new Vector3(1,2,3); Vector3 pos2 new Vector3(4,5,6); var pos3 pos1 pos2; var pos4 pos1 * 2f;推荐写法 var pos3 new Vector3(pos1.x pos2.x, pos1.y pos2.y, …); var pos2 new Vector3(pos1.x * 2f, pos1.y * 2f, …);
51.lua UI变量查找
不推荐写法 find的方式推荐写法 Editor中Prefab绑定lua使用
52.tag比较
不推荐写法 gameObject.Tag “MyTag” 属性访问返回一个字符串跟另外一个字符串比较推荐写法 gameObject.CompareTag(“MyTag”) 实用CompareTag方法内部直接比较避免一次字符串创建
53.能用localposition就不要用position 原因获取position背后会做一系列计算因为涉及到全局坐标需求中能用localposition就用这个
持续更新欢迎补充…