Unity高效编程经验60条分享

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

如果频繁获取组件的xxx.obj.transform,可以在Lua中做一个缓table映射缓存

2.使用泛型必须生成对应类型的wrap文件

  • 错误写法:泛型容器直接使用
  • 正确写法:_GT(typeof(Dictionary<int, long>)然后生成对应的wrap文件,Lua调用避免产生GC

3.使用C#容器如果知道大概的容量尽量指定初始化大小避免自动扩容产生的GC,例如List、Dictionary、Array

  • 错误写法:
    Dictionary<ulong, int> buffTableIndexMap = new Dictionary<ulong, int>();
    List list = new List();
    for (int i = 0; i < 1000; i++)
    {
    list.Add(i);
    }
  • 正确写法:Dictionary<ulong, int> buffTableIndexMap = new Dictionary<ulong, 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
    • 错误写法:频繁调用
    • 正确写法:可以移到相机视野外或者设置透明度
  • 频繁操作组件方法/属性
    • GetComponent
    • AddComponent
    • Find/FindWithTag
    • GetTag
    • Camera.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.物理接口的使用
使用物理接口例如:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值