[英]Why is object pooling not regenerating destroyed objects?
因此,過去幾天我一直在閱讀有關 object 池化的信息,試圖了解它是如何工作的。 好吧,我想我現在基本明白了,但編碼是我的巨大弱點......需要池的游戲是一個簡單的無盡之字折線類型的游戲,隨着玩家前進,平台會生成。 我寫了一個代碼,希望它能工作,但它沒有。 我設置了 20 個平台正在生成,這是可行的,但它們不會在播放器面前禁用和重新啟用。
我附上一張圖片以便更好地理解這是代碼:
public class ObjectPooler : MonoBehaviour
{
public static ObjectPooler current;
public GameObject pooledObject;
public int pooledAmount;
private List<GameObject> pooledObjects;
private void Awake()
{
current = this;
}
void Start()
{
//current = this;
pooledObjects = new List<GameObject>();
for (int i = 0; i < pooledAmount; i++)
{
GameObject obj = Instantiate(pooledObject);
obj.SetActive(false);
pooledObjects.Add(obj);
}
}
public GameObject GetPooledObject()
{
for (int i = 0; i < pooledObjects.Count; i++)
{
if (!pooledObjects[i].activeInHierarchy)
{
return pooledObjects[i];
}
}
return null;
}
}
負責平台生成的腳本:
public class PlatformSpawner : MonoBehaviour
{
public GameObject platform;
public Transform lastPlatform;
SpawnPoint _spawn;
bool stop;
[System.Serializable]
public struct SpawnPoint
{
public Vector3 position;
public Quaternion orientation;
public void Step(float distance)
{
if (Random.value < 0.5)
{
position.x += distance;
orientation = Quaternion.Euler(0, 90, 0);
}
else
{
position.z += distance;
orientation = Quaternion.Euler(0, 0, 0);
}
}
}
private void OnEnable()
{
Invoke("Disable", 1f);
}
void Start()
{
_spawn.position = lastPlatform.position;
_spawn.orientation = transform.rotation;
StartCoroutine(SpawnPlatforms());
}
IEnumerator SpawnPlatforms()
{
while (!stop)
{
GameObject obj = ObjectPooler.current.GetPooledObject();
if (obj == null) yield break; //return
obj.transform.position = lastPlatform.position;
obj.transform.rotation = lastPlatform.rotation;
obj.SetActive(true);
_spawn.Step(1.5f);
var newPlatform = Instantiate(platform, _spawn.position, _spawn.orientation);
yield return new WaitForSeconds(0.1f);
}
}
void Disable()
{
gameObject.SetActive(false);
}
private void OnDisable()
{
CancelInvoke();
}
}
我知道它有點太長了,但它有助於看透一切。 有人可以告訴我我到底需要更改、刪除或做什么嗎? 每一個答案都非常感謝!
簡單解決方案:使用現有解決方案,例如SimplePool 。
或者你可以得到簡單的池,檢查它是如何工作的,然后創建你自己的實現。
困難但有趣的解決方案:讓你的代碼工作。 以下是步驟:
讓您的游戲在沒有池的情況下運行良好。 可以肯定的是,您對游戲玩法本身沒有任何問題。
實施您的游泳池。 object 池中最重要的事情:它只是默認實例化(也許還有銷毀)的替代品。 所以,你的游戲代碼應該對池本身一無所知——它只要求:“在這里創建這個 object 的實例”——就是這樣。 好吧,也許,“把這個 object 帶回池中”。 但是不能返回“null”,也沒有額外的邏輯來處理案例。
在您的 ObjectPooler 代碼中,您在數組中搜索免費(禁用)object,並在找到時返回它。 但是,當所有對象都在使用時,發生了什么? 不再需要的對象如何回到池中以供將來重用? 所以,池應該處理的事情是:
最后一點可以通過多種方式實現。 在 SimplePool 中,您需要手動調用 Despawn(),當您的 object 不再需要(通過屏幕)。 它的好方法,特別是對於插件 - 使用戶能夠為其實現任何自定義邏輯。 但是您可以在一段時間延遲后為每個池化的 object 實現自動消失,或者創建協程,例如 [等待 OnBecameVisible -> 等待 OnBecameInvisible -> Despawn] 或其他 - 這取決於您。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.