向上移动/移动对象然后将第一个元素移动到最后一个索引

我正在Unity3D中构建一个游戏,我试图通过启用和禁用它们而不是实例化和销毁它们来重用GameObjects。

我在GameObject数组中有10个弹簧,每次我使用弹簧时我想从数组中的第一个元素中取出它,将该数组的所有剩余元素移位,然后将第一个Object移动到最后一个索引中。arrays。

这称为对象池。 您不需要从第一个或最后一个删除数组来执行此操作。 有很多方法可以在Unity中存档它。

方法1(推荐):

即使这样可行,但移动数组中的对象也是不必要且低效的。 您可以拥有一个可以移动的索引。 它从0开始,每次请求一个Object时,都将它递增一。 如果索引等于Array.Length - 1 ,则将索引重置为0

 public class ArrayObjectPooling { int amount = 10; GameObject[] objArray; int currentIndex = 0; public ArrayObjectPooling(GameObject objPrefab, string name, int count) { amount = count; objArray = new GameObject[amount]; for (int i = 0; i < objArray.Length; i++) { objArray[i] = UnityEngine.Object.Instantiate(objPrefab, Vector3.zero, Quaternion.identity); objArray[i].SetActive(false); objArray[i].name = name + " #" + i; } } //Returns available GameObject public GameObject getAvailabeObject() { //Get the first GameObject GameObject firstObject = objArray[currentIndex]; //Move the pointer down by 1 shiftDown(); return firstObject; } //Returns How much GameObject in the Array public int getAmount() { return amount; } //Moves the current currentIndex GameObject Down by 1 private void shiftDown() { if (currentIndex < objArray.Length - 1) { currentIndex++; } else { //Reached the end. Reset to 0 currentIndex = 0; } } } 

用法

 public GameObject prefab; void Start() { ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 10); GameObject myObj = arrayPool.getAvailabeObject(); } 

方法2

如果池很小, List足以执行此操作。 请看看Unity的Object Pooling官方教程实现了这一点。 没有必要在这里发布代码。

您只需禁用 List的GameObject即可回收它。 下次需要一个新的时,循环遍历List并返回List中第一个禁用的GameObject。 如果启用,则表示它仍在使用中。

如果列表中未找到禁用的GameObject,则可以Instantiate新的Instantiate ,将其添加到列表中然后将其返回。 这是最简单的方法。 只需观看Unity教程即可获得更多信息。


方法3

使用队列或堆栈。 您可以从池中排队并排队或推送/弹出对象。 如果你做一个简单的研究 - 搜索就有很多实现。


方法4

这只是提到的,因为这是关于如何在数组中向上移动对象然后将第一个值放在数组的最后一个索引中的原始问题。 你不应该使用它。 只是为了certificate它可以完成。

 public class ArrayObjectPooling { int amount = 10; public GameObject[] objArray; public ArrayObjectPooling(GameObject objPrefab, string name, int count) { amount = count; objArray = new GameObject[amount]; for (int i = 0; i < objArray.Length; i++) { objArray[i] = UnityEngine.Object.Instantiate(objPrefab, Vector3.zero, Quaternion.identity); objArray[i].SetActive(false); objArray[i].name = name + " #" + i; } } //Returns available GameObject public GameObject getAvailabeObject() { //Get the first GameObject GameObject firstObject = objArray[0]; //Move everything Up by one shiftUp(); return firstObject; } //Returns How much GameObject in the Array public int getAmount() { return amount; } //Moves the GameObject Up by 1 and moves the first one to the last one private void shiftUp() { //Get first GameObject GameObject firstObject = objArray[0]; //Shift the GameObjects Up by 1 Array.Copy(objArray, 1, objArray, 0, objArray.Length - 1); //(First one is left out)Now Put first GameObject to the Last one objArray[objArray.Length - 1] = firstObject; } } 

用法

 public GameObject prefab; void Start() { ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 3); GameObject myObj = arrayPool.getAvailabeObject(); }