• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

游戏开发

Unity3d Singleton与对象pool

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2019/0325/424.html

Unity3d Singleton与对象pool

 



 
App开发培训单例形式是一切设计形式之中运用最普遍的设计形式之一,而对象池在游戏中相当常用,经过对GameObject的重复应用,能节约珍贵的CPU资源。在本篇文章中将给大家分享下在项目中运用单例形式与对象池的技巧。
 
 
单例形式
 
单例形式,简单说就是类的实例在内存中只存在一份,其中单例形式有2种写法:
 
首先,是继承自MonoBehaviour的单例,需求运用U3D组件和功用能够用这种单例。了解U3D自身单例写法的机制就晓得为啥要这么写了,第一个挂载脚本的对象,就是该单例,后面再怎样反复挂载是无效的。由于挂载的时分就实例化该类了。
    public static ObjectPool instance;   //单例
    //U3D的单例机制,是第一个挂载脚本的对象,就是该单例,后面再怎样反复挂载是无效的。由于挂载的时分就实例化instance了。
    void Awake()
    {
        instance = this;
    }
 
其次,常州网站开发培训不继承MonoBehaviour的单例,全局单例吧,什么场景都能用,不能挂载到U3D物体上。
    private static ObjectPool instance;   //单例
    public ObjectPool GetInstance()
    {
        if (instance == null) 
        {
            instance = new ObjectPool();
        }
        return instance;
    }  
 
对象池
 
思绪:反复创立大量物理和销毁物体,会大量耗费资源,比方:子弹,金币等等,对象池的作用就是创立完了不销毁,只能把它躲藏存入对象池,用一个列表保管数据,需求用的时分再取出来,同时激活它,并且移除列表,这样列表中剩下的就是躲藏能够运用的对象。由于可能有很多物体需求用对象池,所以把个物体的LIST列表存入一个字典。假如对象池中有100个对象,创立90个都是在对象池中激活,只要创立110,才会再重生成10个。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//U3D单例对象池
public  class ObjectPool : MonoBehaviour
    public static ObjectPool instance;   //单例
    public GameObject[] prefabObjects;   //prefab数组
    private Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>();  //对象池字典
    //U3D的单例机制,是第一个挂载脚本的对象,就是该单例,后面再怎样反复挂载是无效的。由于挂载的时分就实例化instance了。
    void Awake()
    {
        instance = this; 
    }
    //从常州企业培训池中获取      //正式项目最好用一个静态类来保管名字,避免出错
    public GameObject GetOut(string GameObjectName, Vector3 vector3)
    {
        GameObject gameObject;   //返回的gameObject
        //假如池中有
        if (pool.ContainsKey(GameObjectName) && pool[GameObjectName].Count > 0)
        {
            //取池里的用
            gameObject = pool[GameObjectName][0];
            gameObject.SetActive(true);
            gameObject.transform.position = vector3;
            //取完移除
            pool[GameObjectName].RemoveAt(0);
        }
       //假如没有
        else
        {
            GameObject prefabObject = null;
            //要生成的prefabObject   prefab数组中的物体名字要和传入的字符串分歧  
            for (int i = 0; i < prefabObjects.Length; i++)
            {
                if (prefabObjects[i].name == GameObjectName)
                {
                    prefabObject = prefabObjects[i];
                }
            }
            //直接创立
            gameObject = (GameObject)GameObject.Instantiate(prefabObject, vector3, Quaternion.identity);
        }
        return gameObject;
    }
    //存入对象池
    public void SetIn(string GameObjectName,GameObject gameObject) 
    {
      //池中没有
      if (!pool.ContainsKey(GameObjectName))
      {   //新建池List
          pool.Add(GameObjectName, new List<GameObject>());
      }
      //存入常州软件技术培训池
      gameObject.SetActive(false);
      pool[GameObjectName].Add(gameObject);
      Debug.Log(pool[GameObjectName].Count);
    }
    //销毁对象池
    public void DestroyPool(string GameObjectName)
    {
        if (pool.ContainsKey(GameObjectName))
        {   //删除对象
            for (int i = 0; i< pool[GameObjectName].Count; i++) 
            {
                Destroy(pool[GameObjectName][i]);
            }
            //移除列表
            pool.Remove(GameObjectName);
        }
    }
留意:运用的时分,从对象池获取,什么中央都能够用,存入对象池这个办法最好在物体自身上,比方子弹上挂着一个,本人就把本身存入对象池。实践运用就用常州平台运营PoolManager插件好了,
 


上篇:上一篇:常州手游开发-Thread,Queue,Lock用法
下篇:下一篇:u3d圆径模糊效果shader