通用框架 单例工具类 对象池优化

为什么使用框架

解耦 开闭原则

单利模板

using System;
    
/*
	子类要想继承父类 需要先执行父类的构造函数
	父类设置成私有 子类无法调用
	
	子类里边可以设置私有 但是父类又错了 因为父类限制了 where T : new() 
	
	通过反射方式 解决私有构造 new 的问题
*/    	


namespace Utility {
    public class Singleton<T> {
        //静态单利
        private static T instance;

        public static T GetInstance(){
            if(instance == null){
                instance = (T)Activator.CreateInstance(typeof(T),true);
            }
            return instance;
        }
    }
}
    

对象池

优化主要三个部分 CPU 内存 显存

Window -----> Profiler 检测性能

对象池是一种优化技术

解决CPU的频繁生成销毁的问题

生成完了不要销毁 放到池子里 用时候 直接从池子里拿

using System.Collections.Generic;
using UnityEngine;

namespace Utility {
    public class ObjectPool : Singleton<ObjectPool>{
        //私有构造
        private ObjectPool(){
            pool = new Dictionary<string,List<GameObject>>();
        }

        //总池子里面存着子池子  子池子里存的都是游戏对象
        private Dictionary<string,List<GameObject>> pool;

        //拿东西或者放回对象池
        //拿

        //通过对象池生成游戏对象
        public GameObject SpawnObject(string name){
            //声明游戏对象
            GameObject needObj;
            //查看是否有该名字对应的子池子    如果有子池子 查看里面有没有东西
            if(pool.ContainsKey(name) && pool[name].Count > 0){
                //返回池子里的第一个
                needObj = pool[name][0];
                //返回后把池子里的0号元素移除
                pool[name].RemoveAt(0);
            }
            else{
                //要不就都没有子池 或者没有对象
                //直接通过Instantiate生成
                needObj = PrefabManager.GetInstance().CreateGameObjectByPrefab(name);
                //修改生成的游戏对象名字,去掉(Clone)
                needObj.name = name;
            }
            //取的时候 设为激活
            needObj.SetActive(true);        
            
            //初始化操作  找抽象
            needObj.GetComponent<ObjectByPool>().ObjectInit();
            
            //返回
            return needObj;
        }

        //回收游戏对象到对象池
        public void RecycleObj(GameObject obj){

            //防止被看到,设为非激活
            obj.SetActive(false);

            //看看有没有对应的对象子池 如果有就放里头 没有开个新池子
            if(pool.ContainsKey(obj.name)){
                //将对象放入子池子里
                pool[obj.name].Add(obj);
            }
            else{//没有子池子
                //创建子池子,把对象放入进去
                pool.Add(obj.name,new List<GameObject>{obj});
            }
            //收尾操作  找抽象
            obj.GetComponent<ObjectByPool>().ObjectDispose();
        }
    }
}

挂在预设体上的脚本

using UnityEngine;
using System.Collections;
using Utility;


public class PoolObject : ObjectByPool {
    
    //定时回收
    protected override void OnEnable(){
        base.OnEnable();//父类里有东西先执行父类的
        StartCoroutine(DelayRecele(3));
    }
    
    public override void ObjectInit(){
        //初始化内容
        gameObject.transform.position = Vector3.zero;
        gameObject.transform.rotation = Quaternion.identity;
        gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
        gameObject.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
    }
    
    public override void ObjectDispose(){
        //收尾内容
    }
    
    //延时回收 					时间间隔
    IEnumerator DelayRecele(float interval){
        //等待几秒钟之后执行
        yield return new WaitForSeconds(interval);
        //回收当前对象
        ObjectPool.GetInstance().RecycleObj(gameObject);
    }
}
using UnityEngine;

namespace Utility {
    //希望别的游戏对象挂在ObjectByPool 或他的子类
    public abstract class ObjectByPool : MonoBehaviour {
        //定义时间节点
        //从表现形态开始  进入对象池设为非激活 离开对象池设为激活
        //写父类的回调函数 修饰符要写protected 要设成 virtual 虚方法 子类里就能重写了
        protected virtual void OnEnable(){//非激活到激活
            //ObjectInit();
        }

        protected virtual void OnDisable(){//激活到非激活
            //ObjectDispose();
        }

        //从对象池出来 做初始化操作
        public abstract void ObjectInit();
        //进入对象池 做收尾操作
        public abstract void ObjectDispose();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值