【问题标题】:How to Move disabled gameObjects from one list to another?如何将禁用的游戏对象从一个列表移动到另一个列表?
【发布时间】:2016-07-28 16:08:48
【问题描述】:

我一直在制作无尽的跑步游戏。我有一组随机生成的瓷砖(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);
    }

非常感谢您的帮助。

【问题讨论】:

    标签: c# unity3d unity5 gameobject


    【解决方案1】:

    您可以在需要时将它们从后面移到前面,而不是停用然后重新激活您的图块,如下所示:

    |---|---|---|---|
    |---|---|---|---|
    
            |
            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 设置为完全填满屏幕的图块数。

    现在您的游戏应该不断生成新的图块,直到有足够多的图块,这样如果您更改最后一个或第一个图块,它就不会显示在屏幕上。然后,一旦达到这个数量,游戏应该取最后一块(不在屏幕上)并将其移到前面(也不应该在屏幕上)。然后你的角色会再次遇到这个图块,另一个屏幕外图块会被移到前面,以此类推。理想情况下,角色看起来像是在无限的路径上

    【讨论】:

    • 那么将NumberOfTilesThatFitOnScreen 设置为填充屏幕的磁贴数是什么意思?
    • 类似NumberOfTilesThatFitOnScreen = (safeZone / tileLength)。如果您看到瓷砖消失/重新出现(当被移到前面时),请增加它。
    • 感谢您的帮助。非常感谢。 :)
    • 即使您执行类似的操作,首先生成的图块也不会参与图块切换过程。我该怎么办?
    • 这些图块在activeTiles 列表中吗?如果不是,您应该将它们添加到列表中
    【解决方案2】:

    只需将磁贴从活动列表移动到停用列表,如下所示:

    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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多