Unity如何从列表中删除GameObject?似乎不适合我

时间:2019-12-06 13:40:13

标签: c# unity3d

编辑:通过添加if(!roomsInProg.Contains(currentRoom)) roomsInProg.Add(currentRoom);感谢@derHugo来解决!

因此,我正在Unity中使用地牢生成器,并在脚本中将正在生成的房间添加到正在进行的房间列表中,然后在完成生成后将其删除,并开始在其上生成下一个列表。

我在这里设置当前房间

currentRoom = Instantiate(roomPrefabs[Random.Range(0, roomPrefabs.Length)], new Vector3(0, 0, 0), Quaternion.identity) as GameObject;

然后在这里,我将该房间添加到正在进行的房间列表中

roomsInProg.Add(currentRoom);

这是我在列表中添加新房间的示例

if (roomScript.connectionsAvailable[0] == true && roomScript.rCheck[0].room == null && n<roomCount) {
        tempRoom = Instantiate(roomPrefabs[Random.Range(0, roomPrefabs.Length)], new Vector3(0, roomDistanceY, 0) + currentRoom.transform.position, Quaternion.identity) as GameObject;
        roomsInProg.Add(tempRoom);
        tempRoom.GetComponent<RoomScript>().directionFromSpawn = 0;
        n++;
        if (n>=roomCount) {
            firstOver = true;
        }
        }

在这里,我要从列表中删除当前房间

if (!firstOver) {
        roomsInProg.Remove(currentRoom);
        currentRoom = roomsInProg[0];
    }
    if (n<roomCount || roomsInProg.Count > 0) {
        Invoke("SpawnRoom", 0.01f);
    }
    }

这里是完整代码,如有必要,https://pastebin.com/C9TKnQPL 其他脚本(如有必要)RoomScript pastebin.com/HPSFJ7RB roomCheck pastebin.com/umNvj9VG SpawnCheck pastebin.com/xkT7QtSJ

1 个答案:

答案 0 :(得分:2)

您拥有Spawn方法

Invoke("SpawnRoom", 0.01f);

然后在SpawnRoom中完成

roomsInProg.Add(currentRoom);

老实说,我没有解析整个代码,但是您在SpawnRoom中所做的最后一件事是

if (n<roomCount || roomsInProg.Count > 0) {
    Invoke("SpawnRoom", 0.01f);
}

因此,在我不知道之间发生什么的情况下,我很可能roomsInProg.Count最后是> 0,这导致您再次调用SpawnRoom并添加相同的{{1 }}再次进入列表。

您应该检查它是否已经存在,并且仅在不喜欢时添加它

currentRoom

通常,您应该强烈地重新考虑您的代码结构,尤其是这些if(!roomsInProg.Contains(currentRoom)) roomsInProg.Add(currentRoom); 调用……使用Coroutine可能会更好。您的大多数Invoke块都应该用if else代替,甚至最好使用一些字典,以便将输入的索引转换为以后要访问的索引。这样可以大大减少您的代码。


只是一个例子

代替使用

switch-case

我会

if (currentRoom.GetComponentInChildren<SpawnCheck>().spawnRoom == false) {
    if (roomScript.directionFromSpawn == 0) {
        availableDoors.Remove(availableDoors[System.Array.IndexOf(availableDoors.ToArray(), 2)]);
        roomScript.connectionsEnabled[2] = true;
        roomScript.connectionsAvailable[2] = false;
        roomScript.connectionsConnected[2] = false;
        roomScript.roomConnections[2].SetActive(false);
    }
    if (roomScript.directionFromSpawn == 1) {
        availableDoors.Remove(availableDoors[System.Array.IndexOf(availableDoors.ToArray(), 3)]);
        roomScript.connectionsEnabled[3] = true;
        roomScript.connectionsAvailable[3] = false;
        roomScript.connectionsConnected[3] = false;
        roomScript.roomConnections[3].SetActive(false);
    }
    if (roomScript.directionFromSpawn == 2) {
        availableDoors.Remove(availableDoors[System.Array.IndexOf(availableDoors.ToArray(), 0)]);
        roomScript.connectionsEnabled[0] = true;
        roomScript.connectionsAvailable[0] = false;
        roomScript.connectionsConnected[0] = false;
        roomScript.roomConnections[0].SetActive(false);
    }
    if (roomScript.directionFromSpawn == 3) {
        availableDoors.Remove(availableDoors[System.Array.IndexOf(availableDoors.ToArray(), 1)]);
        roomScript.connectionsEnabled[1] = true;
        roomScript.connectionsAvailable[1] = false;
        roomScript.connectionsConnected[1] = false;
        roomScript.roomConnections[1].SetActive(false);
    }
}

这使您可以将整个块减少到仅

private Dictionary<int,int> directionToConnectionIndex = new Dictionary<int, int>
    {
        {0, 2},
        {1, 3},
        {2, 0},
        {3, 1}
    };

甚至可能在orser中使用一些if (!currentRoom.GetComponentInChildren<SpawnCheck>().spawnRoom) { var connectionIndex = directionToConnectionIndex[roomScript.directionFromSpawn]; availableDoors.Remove(connectionIndex); roomScript.connectionsEnabled[connectionIndex] = true; roomScript.connectionsAvailable[connectionIndex] = false; roomScript.connectionsConnected[connectionIndex] = false; roomScript.roomConnections[connectionIndex].SetActive(false); } 来限制可能的值。