如何将禁用的游戏对象从一个列表移动到另一个列表

本文关键字:列表 一个 移动 另一个 对象 游戏 | 更新日期: 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;
}

从列表中删除对象时,如果该对象被另一个变量引用,则该对象不会被销毁。