📜  游戏对象的统一列表 - C# (1)

📅  最后修改于: 2023-12-03 14:56:09.514000             🧑  作者: Mango

游戏对象的统一列表 - C#

在游戏开发中,我们经常需要对游戏对象进行操作,如创建、销毁、查找等。为了方便管理和操作游戏对象,Unity 提供了一个对象池来统一管理游戏对象。

对象池的基本功能
  • 创建游戏对象

    GameObject obj = ObjectPool.Spawn("Prefab Name", Vector3.zero, Quaternion.identity);
    
  • 销毁游戏对象

    ObjectPool.Despawn(obj);
    
  • 查找游戏对象

    GameObject obj = ObjectPool.Find("Prefab Name");
    
  • 对象池自动化

    public class MyObject : MonoBehaviour
    {
        private void OnEnable()
        {
            ObjectPool.Register(this.gameObject);
        }
    
        private void OnDisable()
        {
            ObjectPool.Unregister(this.gameObject);
        }
    }
    
对象池的实现方式

我们可以通过创建一个静态的对象池类,来对游戏对象进行统一管理。在该类中,我们可以使用一个字典来存储游戏对象,键为游戏对象的名字,值为游戏对象。

对象池类的代码如下:

public static class ObjectPool
{
    private static Dictionary<string, Queue<GameObject>> objectPoolDictionary = new Dictionary<string, Queue<GameObject>>();

    public static GameObject Spawn(string prefabName, Vector3 position, Quaternion rotation)
    {
        if (objectPoolDictionary.ContainsKey(prefabName))
        {
            GameObject obj = null;
            Queue<GameObject> queue = objectPoolDictionary[prefabName];
            while (queue.Count > 0)
            {
                obj = queue.Dequeue();
                if (obj != null)
                {
                    obj.transform.position = position;
                    obj.transform.rotation = rotation;
                    obj.SetActive(true);
                    return obj;
                }
            }
        }

        GameObject prefab = Resources.Load<GameObject>("Prefabs/" + prefabName);
        if (prefab == null)
        {
            Debug.LogError("Not found prefab: " + prefabName);
            return null;
        }

        GameObject newObj = Instantiate(prefab, position, rotation);
        if (!objectPoolDictionary.ContainsKey(prefabName))
        {
            objectPoolDictionary.Add(prefabName, new Queue<GameObject>());
        }
        objectPoolDictionary[prefabName].Enqueue(newObj);

        return newObj;
    }

    public static void Despawn(GameObject obj)
    {
        if (obj == null)
        {
            Debug.LogError("Object is null.");
            return;
        }
        obj.SetActive(false);
        if (!objectPoolDictionary.ContainsKey(obj.name))
        {
            objectPoolDictionary.Add(obj.name, new Queue<GameObject>());
        }
        objectPoolDictionary[obj.name].Enqueue(obj);
    }

    public static GameObject Find(string prefabName)
    {
        if (objectPoolDictionary.ContainsKey(prefabName))
        {
            Queue<GameObject> queue = objectPoolDictionary[prefabName];
            foreach(GameObject obj in queue)
            {
                if (!obj.activeInHierarchy)
                {
                    return obj;
                }
            }
        }
        return null;
    }

    public static void Register(GameObject obj)
    {
        if (obj == null)
        {
            Debug.LogError("Object is null.");
            return;
        }
        if (!objectPoolDictionary.ContainsKey(obj.name))
        {
            objectPoolDictionary.Add(obj.name, new Queue<GameObject>());
        }
        objectPoolDictionary[obj.name].Enqueue(obj);
    }

    public static void Unregister(GameObject obj)
    {
        if (obj == null)
        {
            Debug.LogError("Object is null.");
            return;
        }
        if (objectPoolDictionary.ContainsKey(obj.name))
        {
            objectPoolDictionary[obj.name].Dequeue();
        }
    }
}
总结

通过对象池的统一管理,我们可以较为轻松地管理游戏对象,并且能够有效地减少游戏对象的创建和销毁次数,从而提高游戏的性能。