编辑:通过添加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
答案 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);
}
来限制可能的值。