Skip to content

Instantly share code, notes, and snippets.

@HassakuTb
Created June 6, 2020 13:38
Show Gist options
  • Save HassakuTb/ee3a24360a43cfdbfb67e8029f92aa66 to your computer and use it in GitHub Desktop.
Save HassakuTb/ee3a24360a43cfdbfb67e8029f92aa66 to your computer and use it in GitHub Desktop.
オブジェクトプール
using System.Collections;
using UnityEngine;
public class CubeForPool : MonoBehaviour, IPoolable<CubeForPool>
{
private ObjectPool<CubeForPool> ObjectPool { get; set; }
public void Initialize(ObjectPool<CubeForPool> objectPool)
{
ObjectPool = objectPool;
}
public void OnRent()
{
// 2秒で死ぬ
StartCoroutine(DestroySelfCoroutine(2.0f));
}
public void OnReturn()
{
// nop
}
private IEnumerator DestroySelfCoroutine(float delay)
{
yield return new WaitForSecondsRealtime(delay);
ObjectPool.Return(this);
}
}
using UnityEngine;
public class CubeGeneratorForPool : MonoBehaviour
{
[SerializeField] private Transform container;
[SerializeField] private CubeObjectPool objectPool;
[SerializeField] private float generateCountPerSec = 100f;
// まえのフレームの生成個数の超過分
private float remainOfGenerated = 0;
private static Vector3 CreateRandomPosition()
{
return new Vector3(Random.Range(-5f, 5f), Random.Range(-5f, 5f), Random.Range(-5f, 5f));
}
private void GenerateCube()
{
CubeForPool cube = objectPool.Rent();
cube.transform.parent = container;
cube.transform.position = CreateRandomPosition();
}
private void Update()
{
remainOfGenerated += Time.deltaTime * generateCountPerSec;
while (remainOfGenerated > 1f)
{
GenerateCube();
remainOfGenerated -= 1f;
}
}
}
using System;
[Serializable]
public class CubeObjectPool : ObjectPool<CubeForPool> {}
using UnityEngine;
/// <summary>
/// プール可能なコンポーネントはこのインターフェースを実装しなければならない
/// </summary>
/// <typeparam name="T">プール可能なコンポーネントクラス</typeparam>
public interface IPoolable<T> where T : Component, IPoolable<T>
{
/// <summary>
/// オブジェクト生成時に一度だけ呼び出される
/// </summary>
/// <param name="objectPool">オブジェクトプールインスタンス</param>
void Initialize(ObjectPool<T> objectPool);
/// <summary>
/// オブジェクトが貸し出されるときに呼び出される
/// </summary>
/// <remarks>オブジェクトがアクティブになった後貸し出される前に呼ばれる</remarks>
void OnRent();
/// <summary>
/// オブジェクトが返却されるときに呼び出される
/// </summary>
/// <remarks>返却直後、オブジェクトが非アクティブになる前に呼ばれる</remarks>
void OnReturn();
}
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
/// <summary>
/// オブジェクトプール
/// </summary>
/// <typeparam name="T">プールするオブジェクトの型</typeparam>
public class ObjectPool<T> : MonoBehaviour where T: Component, IPoolable<T>
{
/// <summary>
/// 生成するオブジェクトのprefab
/// </summary>
[SerializeField] private T prefab;
/// <summary>
/// 貸し出されていないオブジェクトのリスト
/// </summary>
readonly private Stack<T> inactiveObjects = new Stack<T>();
/// <summary>
/// プール対象のオブジェクトを生成する
/// </summary>
/// <returns>生成されたオブジェクト</returns>
private T InstantiateItem()
{
T newItem = Instantiate(prefab);
newItem.Initialize(this);
newItem.gameObject.SetActive(false);
return newItem;
}
/// <summary>
/// オブジェクトを貸し出す
/// プールされているオブジェクトが無い場合は生成する
/// </summary>
/// <returns>activeなオブジェクト</returns>
public T Rent()
{
if (!inactiveObjects.Any())
{
inactiveObjects.Push(InstantiateItem());
}
T obj = inactiveObjects.Pop();
obj.gameObject.SetActive(true);
obj.OnRent();
return obj;
}
/// <summary>
/// 貸し出されたオブジェクトを返却する
/// </summary>
/// <param name="obj">返却するオブジェクト</param>
public void Return(T obj)
{
obj.OnReturn();
obj.gameObject.SetActive(false);
inactiveObjects.Push(obj);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment