Unity游戏代码优化(持续更新)

虽然说美术资源优化会提高性能,不过好的代码可以提高很多性能

这些大部分都出现在我的项目,一些不好的代码,功能是可以就是用了比较耗性能的实现方式

1.在Update里面一直new

例子:最近看到同事写的定时器,他是用字典存储,然后每次update都new list(keys)来遍历定时器和移除定时器

因为foreach下不能移除字典数据,所以用这种new keys

//错误写法
public class ErrorInvoke
{
    Dictionary<string, InvokeData> dic = new Dictionary<string, InvokeData>();

    void Update()
    {
        List<string> list = new List<string>(dic.Keys);
        for(int i=0;i<list.Count;i++)
        {
            //满足情况就移除字典
        }
    }
}

解决方案:用列表来存储相关定时器,update只遍历列表,字典存储列表的引用就好


//修改之后写法
public class FixInvoke
{
    Dictionary<string, object> dic = new Dictionary<string, object>();
    List<InvokeData> list = new List<InvokeData>();

    void Update()
    {
        for(int i=list.Count;i-->0;)
        {
            //满足条件移除列表移除字典
        }
    }
}

2.太多装箱和拆箱

这个东西不用说太多就是目标类型->object装箱,object->目标类型拆箱

这个用的最多可能就是事件系统,我发送事件里面可以有多个参数,这些参数类型不定,然后到最后消息回调里面进行类型转换,频繁的装箱拆箱会引起内存问题,可以使用避免装箱拆箱的事件系统

我同事写的事件事件系统全部用parma object[],因为战斗和ui之间的通信通过事件来,如果一直update来发送事件,装箱拆箱很频繁,我是不建议这么写事件系统

可以参考这个事件系统https://blog.csdn.net/SnoopyNa2Co3/article/details/84971510

3.遍历列表移除

很多情况我们遍历列表来更新数据,如果数据已经没用的情况要从list移除

很多情况的写法是这样的,把移除的存起来,遍历完再移除

如果数据没有先后顺序问题的情况可以下面优化

存起来移除的代码

public class Temp1
{
    List<datat> list = new List<datat>();

    List<datat> removeList = new List<datat>();

    void Update()
    {
        datat temp;
        for (int i=0;i<list.Count;i++)
        {
            temp = list[i];
            if(temp.Remove)
            {
                removeList.Add(temp);
            }
        }
        if(removeList.Count > 0)
        {
            for(int i=0;i<removeList.Count;i++)
            {
                list.Remove(removeList[i]);
            }
            removeList.Clear();
        }
    }
}

下面是优化过的代码

public class Temp2
{
    List<datat> list = new List<datat>();

    void Update()
    {
        datat temp;
        for (int i = list.Count; i-->0 ;)
        {
            temp = list[i];
            if (temp.Remove)
            {
                list.RemoveAt(i);
            }
        }
    }
}

4.关于反射的使用

反射有什么好处,其实就是少写一些代码,方便一点

就例如:后端返回的协议号和对应的proto,来进行序列化数据

最稳的方法就是手写协议号对应的proto类,不过太繁琐(其实可以用工具生成,其实最好)

这方法消耗不大,不过我同事采用等协议返回来再进行反射获取类,再实例化类。如果协议通信多了性能消耗也大

这种是不可以接受的

1.游戏初始化的时候进行绑定

2.就是用工具进行绑定代码的生成

反射着东西能不用尽量不用

5.频繁GetComponent

一般来说初始化的时候才会GetComponent,如果在update里面出现GetComponent或者频繁,这代码肯定有问题

尤其UI上面出现这种基本都是要改。拒绝没必要的性能消耗

6.功能没分模块,代码乱导致查bug麻烦

某个功能模块尽量写到一起,方便扩展和查看

例如:一个角色可以分很多个模块(控制器)

数据控制器(生命值计算之类),buff控制器,技能控制器(分被动和主动),武器控制器(切换武器逻辑),动作控制器(封装各种动作接口),受击控制器(受击击退),操作控制器(控制移动攻击),死亡控制器(多种死亡类型)如果还有其他特殊的可以加,如果这一大堆写到一个脚本里面,那是一个噩梦,查太麻烦,脚本太庞大,改动麻烦

发布了63 篇原创文章 · 获赞 37 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/SnoopyNa2Co3/article/details/98845661