C# Unity 对象池 【及其简便】

C# Unity 对象池 【及其简便】

使用不到40行代码实现一个及其简便的对象池或引用池

1.Pool(当做引用池进行使用)

public static class Pool<T>
{
    private static readonly Queue<T> PoolQueue = new Queue<T>();

    public static int Count => PoolQueue.Count;

    public static T Rent()
    {
        return PoolQueue.Count == 0 ? Activator.CreateInstance<T>() : PoolQueue.Dequeue();
    }

    public static T Rent(Func<T> generator)
    {
        return PoolQueue.Count == 0 ? generator() : PoolQueue.Dequeue();
    }

    public static void Return(T t)
    {
        if (t == null)
            return;
        PoolQueue.Enqueue(t);
    }

    public static void Return(T t,Action<T> reset)
    {
        if (t == null)
            return;
        reset(t);
        PoolQueue.Enqueue(t);
    }

    public static void Clear()
    {
        PoolQueue.Clear();
    }
}

2.使用

public class MyPool1
{
    public int Age;
    public string Name;
}
public class TestPool : MonoBehaviour
{
    void Start()
    {
        MyPool1 myPool1 = Pool<MyPool1>.Rent();
        myPool1.Age = 18;
        myPool1.Name = "zzs";
        Debug.Log(myPool1.Age);
        Debug.Log(myPool1.Name);
        Pool<MyPool1>.Return(myPool1);
        Debug.Log(Pool<MyPool1>.Count);
        MyPool1 myPool11 = Pool<MyPool1>.Rent();
        myPool11.Age = 20;
        myPool11.Name = "xxx";
        Debug.Log(myPool11.Age);
        Debug.Log(myPool11.Name);
        Debug.Log(Pool<MyPool1>.Count);
    }
}

3.AbstractPool(当作对象池使用)

public abstract class AbstractPool<T>
{
    private readonly Action<T> _reset;
    private readonly Func<T> _generator;
    private readonly Stack<T> _objects = new Stack<T>();
    public int Count => _objects.Count;

    protected AbstractPool(Func<T> generator, Action<T> reset, int initialCapacity = 0)
    {
        _generator = generator;
        _reset = reset;
        for (var i = 0; i < initialCapacity; ++i)
        {
            _objects.Push(generator());
        }
    }

    public T Rent()
    {
        return _objects.Count > 0 ? _objects.Pop() : _generator();
    }

    public void Return(T item)
    {
        _reset(item);
        _objects.Push(item);
    }

    public void Clear()
    {
        _objects.Clear();
    }
}

4.使用

public class MyPool2 : AbstractPool<GameObject>
{
    public MyPool2(Func<GameObject> generator, Action<GameObject> reset, int initialCapacity = 0) : base(generator,reset,initialCapacity)
    {

    }
}
public class TestPool2 : MonoBehaviour
{
    private MyPool2 myPool2;
    [SerializeField] private GameObject m_Prefab;
    void Start()
    {
        myPool2 = new MyPool2(GeneratorGameObjectHandler, ResetGameObjectHandler, 5);
    }

    private void ResetGameObjectHandler(GameObject go)
    {
        go.SetActive(false);
    }

    private GameObject GeneratorGameObjectHandler()
    {
        GameObject go = Instantiate(m_Prefab);
        go.SetActive(false);
        return go;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            GameObject go = myPool2.Rent();
            go.SetActive(true);
            StartCoroutine(HideGo(go));
        }
    }

    private IEnumerator HideGo(GameObject go)
    {
        yield return new WaitForSeconds(3f);
        myPool2.Return(go);
    }
}

你可能感兴趣的:(c#,unity)