zoukankan      html  css  js  c++  java
  • Unity之设计模式:单例模式和对象池模式

    1. 单例模式

    单例模式原则:

    1. 只能有一个实例。
    2. 必须自己创建自己。
    3. 必须给所有其他对象提供这一实例。

    目的:第一条保证仅有一个实例(私有化构造函数),第二、三条保证提供一个访问它的全局访问点(提供一个供访问的公共方法/属性)。

    优点:避免一个全局使用的类被频繁的创建与销毁。

     

     1 public class SingleTon<T> : MonoBehaviour where T : Component
     2 {
     3     private static T instance;
     4     public static T Instance //提供对外访问的属性
     5     {
     6         get
     7         {
     8             if (instance == null)  //如果没有实例化,那就实例化一个
     9             {
    10                 if (FindObjectsOfType<T>().Length > 1)  //查找挂载了这个脚本的物体,如果超过1个,多个物体挂载了不符合单例模式
    11                     Debug.LogError("instance count>1");
    12                 instance = FindObjectOfType<T>(); //挂载在一个物体身上了
    13                 if (instance == null) //没有挂载在任何物体身上
    14                 {
    15                     GameObject go = new GameObject(); //创建一个空物体
    16                     go.name = typeof(T).ToString();  //物体名就是类型名
    17                     instance = go.AddComponent<T>(); //把这个脚本挂载上去
    18                 }
    19             }
    20             return instance;
    21         }
    22     }
    23 }

    2. 对象池模式

    目的:需要频繁的创建和销毁的物体,比如怪兽、金币、障碍物... 频繁的创建和销毁非常耗费资源,不如游戏一开始就创建出来一堆,先隐藏起来,要使用的时候取消隐藏(从池子中取出),不使用了再隐藏(放回池子)。

    案例:结合单例模式,做一个道具生成和销毁对象池。要求主池子掌控所有物体的生成和销毁(主池子只有一个),子池子提供共有的方法和特征(取出、放回)。

    1)提前把道具的预制体做好,放在资源文件夹下。

     2)写子池子逻辑:从子池子中取出、放回子池子、放回所有物体

     1 public class SubPool
     2 {
     3     List<GameObject> subPool = new List<GameObject>();
     4     GameObject prefab;
     5 
     6     public SubPool(GameObject pref)
     7     {
     8         prefab = pref;
     9     }
    10     public GameObject OutPool() //从池子中取出
    11     {
    12         GameObject obj = null;
    13         foreach (GameObject go in subPool) //找到一个被隐藏的物体,取出来
    14         {
    15             if (go.activeSelf == false)
    16                 obj = go;
    17         }
    18         if (obj == null)  //池子里没有被隐藏的物体了,预存的不够用了,再生成一个
    19         {
    20             obj = GameObject.Instantiate(prefab);
    21             subPool.Add(obj);  //把新生成的也加到池子里
    22         }
    23         obj.SetActive(true); //把找到的这个物体显示出来(取出来)
    24         return obj;
    25     }
    26     public void InputPool()  //放回池子中
    27     {
    28         if (subPool.Count > 0)
    29         {
    30             foreach(GameObject go in subPool)
    31             {
    32                 if (go.activeSelf == true)
    33                 {
    34                     go.SetActive(false);
    35                     break;
    36                 }
    37             }
    38         }
    39     }
    40     public void InputAllObject()  
    41     {
    42         foreach (GameObject go in subPool)
    43         {
    44             if (go.activeSelf == true)
    45                 InputPool();
    46         }
    47     }
    48 }

    3)写主池子逻辑,管理所有子池子。

     1 public class ObjManager : SingleTon<ObjManager>
     2 {
     3     private Dictionary<string, SubPool> PoolDic = new Dictionary<string, SubPool>();  //用字典掌管所有的子池子
     4 
     5     public GameObject OutPool(string name) 
     6     {
     7         if (PoolDic.ContainsKey(name) == false) //如果主池子不包含该对象,new一个子池子,添加进主池子中
     8         {
     9             GameObject obj = Resources.Load("Prefabs/" + name) as GameObject;
    10             SubPool subpool = new SubPool(obj);
    11             PoolDic.Add(name, subpool);
    12         }
    13         SubPool subPool = PoolDic[name];
    14         return subPool.OutPool();
    15     }
    16     public void InputPool(string objName)
    17     {
    18         PoolDic[objName].InputPool();
    19     }
    20     public void InputAllObject()
    21     {
    22         foreach (SubPool sp in PoolDic.Values)
    23             sp.InputAllObject();
    24     }
    25 }
  • 相关阅读:
    C# 操作XML
    js把字符串(yyyymmdd)格式转换成日期格式(yyyy-mm-dd)
    解析GZIP压缩的网页
    访问修饰符
    c# 多态中 Virtual与override的作用
    C# 中 ref 和out 的区别
    C# .net 中文手册地址
    js获取URL参数
    几种Css前端框架资料
    android 检查能否上网
  • 原文地址:https://www.cnblogs.com/tomatokely/p/15497643.html
Copyright © 2011-2022 走看看