我在Unity3D中构建游戏,我试图通过启用和禁用它们来重用GameObjects,而不是实例化和销毁它们。
我在GameObject数组中有10个弹簧,每次我使用弹簧时我想从数组中的第一个元素中取出它,将该数组的所有剩余元素移动,然后将第一个Object移动到最后一个数组中的索引。
答案 0 :(得分:2)
这称为对象池。您不需要从第一个或最后一个删除数组来执行此操作。有很多方法可以在Unity中存档它。
方法1(推荐):
尽管可行,但在数组中移动对象是不必要且低效的。您可以拥有一个可以移动的索引。它从0
开始,每次请求对象时,都会将其递增1。如果索引等于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;
}
}
}
<强> USAGE 强>:
public GameObject prefab;
void Start()
{
ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 10);
GameObject myObj = arrayPool.getAvailabeObject();
}
方法2 :
如果池小, List
就足够了。请take看看Unity的Object Pooling官方教程实现了这一点。没有必要在这里发布代码。
您只需禁用 List
中的GameObject即可回收它。下次需要一个新的时,循环遍历List
并返回List
中第一个禁用的GameObject。如果启用,则表示它仍在使用中。
如果在List
中未找到禁用的GameObject,则可以Instantiate
新的GameObject,将其添加到列表中然后返回。这是最简单的方法。只需观看Unity教程即可获得更多信息。
方法3 :
使用队列或堆栈。您可以从池中排队并排队或推送/弹出对象。如果您对此进行简单的研究,那么有很多实现。
方法4 :
这只是提到的,因为这是关于如何在数组中向上移动对象然后将第一个值放在数组的最后一个索引中的原始问题。你不应该使用它。只是为了表明可以完成。
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;
}
}
<强> USAGE 强>:
public GameObject prefab;
void Start()
{
ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 3);
GameObject myObj = arrayPool.getAvailabeObject();
}