如何将禁用的游戏对象从一个列表移动到另一个列表
本文关键字:列表 一个 移动 另一个 对象 游戏 | 更新日期: 2023-09-27 17:59:15
我一直在制作一款无尽的跑步游戏。我有一组瓦片(4个atm),我随机生成。出于优化目的,我决定不再在玩家运行后实例化和销毁游戏对象,尽管它确实会禁用它们,并在需要从停用的瓦片中生成瓦片时禁用它们。我使两个列表处于活动状态和停用状态,这两个列表将执行上述场景。我设法禁用了它们,但我不知道如何将它们添加到禁用列表中,并在何时生成它们。需要。我怎样才能做到。
这是代码和我迄今为止所做的工作。
TileManager.cs
void Update ()
{
//Vector3 offset = new Vector3(0f, 0f, Time.time * speed);
//GameObject go;
//go.transform.SetParent(transform);
if (playerTransform.position.z - safeZone > (spawnZ - amtOfTilesOnScreen * tileLength))
{
SpawnTile();
DeleteTile();
}
}
private void DeleteTile()
{
//Destroy(activeTiles[0]);
activeTiles[0].SetActive(false);
activeTiles.RemoveAt(0);
//deactivatedTiles.RemoveAt(0);
}
private void SpawnTile(int prefabIndex = -1)
{
GameObject go;
if (prefabIndex == -1)
{
go = Instantiate(tilePrefabs[RandomPrefabIndex()]) as GameObject;
}
else
{
go = Instantiate(tilePrefabs[prefabIndex]) as GameObject;
}
go.transform.SetParent(transform);
go.transform.position = Vector3.forward * spawnZ;
spawnZ += tileLength;
activeTiles.Add(go);
//go.SetActive(false);
//if (deactivatedTiles != null)
//{
// Debug.Log("Has a Tile");
// deactivatedTiles[0].SetActive(true);
//}
//Debug.Log(deactivatedTiles);
}
如有帮助将不胜感激。
您可以在需要时将瓷砖从后面移动到前面,而不是停用然后重新激活瓷砖,如下所示:
|---|---|---|---|
|---|---|---|---|
|
V
|---|---|---|---|
|---|---|---|---|
(第一张图片是旧状态,第二张图片是之后的状态)。代替
if (playerTransform.position.z - safeZone > (spawnZ - amtOfTilesOnScreen * tileLength)) {
SpawnTile();
DeleteTile();
}
做一些类似的事情
if (playerTransform.position.z - safeZone > (spawnZ - amtOfTilesOnScreen * tileLength)) {
if (activeTiles.Count() < (NumberOfTilesThatFitOnScreen + 1)) {
var spawnedTile = SpawnTileAtFront();
activeTiles.Add(spawnedTile);
} else {
var movedTile = activeTiles[0];
MoveTileToFront(movedTile);
//Puts the moved tile at the end of the array, so the next tile that will be moved is always the one in back
activeTiles.RemoveAt(0);
activeTiles.Add(movedTile);
}
}
然后像这样实现这两种方法:
private void MoveTileToFront(GameObject tile)
{
tile.transform.position = Vector3.forward * spawnZ;
spawnZ += tileLength;
}
private GameObject SpawnTileAtFront(int prefabIndex = -1)
{
GameObject go;
if (prefabIndex == -1)
{
go = Instantiate(tilePrefabs[RandomPrefabIndex()]) as GameObject;
}
else
{
go = Instantiate(tilePrefabs[prefabIndex]) as GameObject;
}
go.transform.SetParent(transform);
MoveTileToFront(go);
return go;
}
将NumberOfTilesThatFitOnScreen
设置为完全填充屏幕的分块数。
现在,你的游戏应该不断生成新的互动程序,直到有足够的互动程序为止,这样,如果你更改了最后一个或第一个互动程序,它就不会显示在屏幕上。然后,一旦达到这个数量,游戏就应该拿走最后一块瓷砖(不在屏幕上),并将其移动到前面(也不应该在屏幕上。)。然后你的角色将再次遇到这个瓦片,另一个屏幕外的瓦片将被移到前面,以此类推。理想情况下,它看起来像是角色在一个无限路径
只需将磁贴从活动列表移动到停用列表,如下所示:
private void DisposeActiveTile(int index)
{
GameObject unused_tile = activeTiles[index];
activeTiles.RemoveAt(index);
deactivatedTiles.Add(unused_tile);
}
private GameObject GetLastUnusedTile()
{
if(deactivatedTiles.Count == 0)
return null;
int last_index = deactivatedTiles.Count - 1;
GameObject unused_tile = deactivatedTiles[last_index];
deactivatedTile.RemoveAt(last_index);
return unused_tile;
}
从列表中删除对象时,如果该对象被另一个变量引用,则该对象不会被销毁。