我在Unity3D中構建遊戲,我試圖通過啓用和禁用它們來重用GameObjects,而不是實例化和銷燬它們。移動/移動數組中的對象,然後將第一個元素移動到最後一個索引
我在GameObject數組中有10個彈簧,每當我使用彈簧時,我想從數組中的第一個元素中取出它,將該數組的所有剩餘元素向上移動,然後將第一個對象移動到數組中的最後一個索引。
我在Unity3D中構建遊戲,我試圖通過啓用和禁用它們來重用GameObjects,而不是實例化和銷燬它們。移動/移動數組中的對象,然後將第一個元素移動到最後一個索引
我在GameObject數組中有10個彈簧,每當我使用彈簧時,我想從數組中的第一個元素中取出它,將該數組的所有剩餘元素向上移動,然後將第一個對象移動到數組中的最後一個索引。
這被稱爲對象池。您不需要從第一個或最後一個移除數組來執行此操作。有很多方法可以在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;
}
}
}
用法:
public GameObject prefab;
void Start()
{
ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 10);
GameObject myObj = arrayPool.getAvailabeObject();
}
方法2:
List
就足以做到這一點如果池小。請致電take查看Unity的Object Pooling官方教程。這裏不需要發佈代碼。
您只需禁用遊戲對象在List
回收它。下次需要一個新的時候,循環List
並返回List
中第一個禁用的遊戲對象。如果啓用,這意味着它仍在使用中。
如果在List
中找不到禁用的遊戲對象,則可以將Instantiate
一個新的,添加到列表中,然後返回它。這是做這件事最簡單的方法。只需觀看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;
}
}
用法:
public GameObject prefab;
void Start()
{
ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 3);
GameObject myObj = arrayPool.getAvailabeObject();
}
是的想過,但不想檢查GameObjects是否啓用。認爲可能有某種類型的數組或列表中的操作只是將GameObject引發到數組/列表的末尾。這樣我就可以每次使用數組中的第一個遊戲對象,沒有檢查 – LooMeenin
我以前見過那個教程,我過去使用過對象池,但是我認爲這種場景我更喜歡使用數組或列表某種具有我描述的操作的東西。如果沒有這樣的操作,那麼我會找出其他的東西。 – LooMeenin
@LooMeenin **我試圖通過啓用和禁用它們來重用GameObjects,而不是實例化和銷燬它們。**現在您說您不想檢查它們是否啓用/禁用?爲什麼甚至打擾首先啓用/禁用它們?你想使用數組,如果你需要超過10個彈簧呢?他們在比賽中是否永遠保證10? – Programmer
爲什麼不使用,在此添加禁用的元素隊列,並在需要的時候,你從它出隊獲得以前禁用的情況下,僅需要被重新啓用。爲什麼是數組? – ray
@ray - 不知道,只是認爲它可能有一個操作來做我正在做的事!之前從未使用過隊列。 – LooMeenin
@LooMeenin:您應該檢查文檔,看看在嘗試編寫代碼之前,類是否提供您正在查找的操作,以便發現情況並非如此。如果你之前從未使用過隊列(這是一個基本的數據結構),那麼在深入研究或瞭解遊戲編程之前,你可能需要更好地理解一些基礎知識。 – ray