我正在尝试开发我的游戏中的功能,该功能加载一个List中填充的总共8个随机场景,然后在加载场景后从列表forestSceneIndexes = new List<int>();
中删除。这样当加载下一个随机场景时,它会从列表中的现有场景中选择,等等。
我要做的第一件事是使用函数填充我的列表:
private IEnumerator DoInitSceneIndexList()
{
// Initialize scene name list
for (int i = 0; i < numberOfForestScenes; i++)
{
forestSceneIndexes.Add(firstForestSceneIndexNumber + i);
Debug.Log("Scene index " + forestSceneIndexes[i].ToString() + " added to int list.");
}
yield return new WaitForEndOfFrame();
initSceneList = false;
}
之后我在函数DoGetRandomScene
中得到随机场景private IEnumerator DoGetRandomScene()
{
// Get scene name from random pick
randomSceneIndex = Random.Range(firstForestSceneIndexNumber, (firstForestSceneIndexNumber + forestSceneIndexes.Count) - 1);
yield return new WaitForEndOfFrame();
StartCoroutine(DoRemoveRandomSceneFromList());
// Load selected scene
StartCoroutine(DoLoadScene(randomSceneIndex));
}
一旦我得到随机场景,我就立即从列表中删除该索引:
private IEnumerator DoRemoveRandomSceneFromList()
{
// Remove selected scene from list
forestSceneIndexes.Remove(randomSceneIndex);
yield return new WaitForEndOfFrame();
}
然后我将randomSceneIndex传递给DoLoadScene()函数
private IEnumerator DoLoadScene(int sceneIndex)
{
yield return new WaitForEndOfFrame();
SceneManager.LoadScene(sceneIndex, LoadSceneMode.Single);
}
我的问题是它无法正常工作,它似乎开始没有前几个场景,但它只是继续重新加载相同的场景一旦它下降到约3个场景。我不确定我的错误,任何帮助都将不胜感激!下面还添加了完整的脚本。谢谢!
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine.Networking;
public class ForestGameManager : NetworkBehaviour
{
public static ForestGameManager fgm = null; // create singleton
ForestSceneTimer forestSceneTimer;
[Header("Network Prefab")]
public GameObject serverNetworkManagerPrefab;
[Header("Forest Game Manager")]
private int fgmIndex;
private int firstForestSceneIndexNumber;
private int lastForestSceneIndexNumber;
private bool _isInitialized;
[Header("Forest Scenes")]
[TextArea(1, 1)]
public string forestSceneNotes = "Please place all Forest Scenes after Forest Loader scene";
public int numberOfForestScenes;
private float sceneCountdownLength = 15.0f;
private List<int> forestSceneIndexes;
private int randomSceneIndex;
private bool initSceneList = true;
private int currentSceneIndex;
[Header("Forest Animal Management")]
public int maxAnimalCount = 4;
public List<ForestAnimal> forestAnimals;
private void Awake()
{
//DontDestroyOnLoad(this.gameObject);
StartCoroutine(DoInitForestGameManager());
StartCoroutine(DoInitServerNetworking());
fgmIndex = SceneManager.GetActiveScene().buildIndex;
firstForestSceneIndexNumber = fgmIndex + 1;
//Debug.Log("firstForestSceneIndexNumber Index is : " + firstForestSceneIndexNumber);
forestSceneTimer = GetComponent<ForestSceneTimer>();
}
private void Start()
{
if (!this._isInitialized)
{
forestAnimals = new List<ForestAnimal>();
forestSceneIndexes = new List<int>();
lastForestSceneIndexNumber = ((firstForestSceneIndexNumber + numberOfForestScenes) - 1);
if (initSceneList)
{
StartCoroutine(DoInitSceneIndexList());
StartCoroutine(DoGetRandomScene());
}
Debug.Log("There are " + numberOfForestScenes + " forest scenes in MasterLoader.");
this._isInitialized = true;
}
else
{
this.forestAnimals.Clear(); //I assume you can clear the list on scene change
}
InvokeRepeating("CheckAnimalCount", 0, 1f);
InvokeRepeating("CheckRemainingScenes", 0, 10f);
}
private void CheckAnimalCount()
{
if (forestAnimals.Count >= maxAnimalCount)
{
GameObject toDestroy = forestAnimals[0].forestAnimalGO;
forestAnimals.RemoveAt(0);
StartCoroutine(ExplodedMesh(toDestroy));
//yield return new WaitForSeconds(1f);
}
Debug.Log("Checking animal count");
}
private void CheckRemainingScenes()
{
if (currentSceneIndex >= firstForestSceneIndexNumber && currentSceneIndex <= lastForestSceneIndexNumber)
{
// If all forest scenes have been used, re-initialize scene name list and pick the next random scene
if (forestSceneIndexes.Count == 0)
{
StartCoroutine(DoInitSceneIndexList());
StartCoroutine(DoGetRandomScene());
Debug.Log("Out of scenes, re-initializing scene list.");
}
//yield return new WaitForSeconds(1f);
Debug.Log("Checking remaining scenes");
}
}
private IEnumerator ExplodedMesh(GameObject toDestroy)
{
MeshExploder meshExploder = toDestroy.transform.GetChild(0).gameObject.AddComponent<MeshExploder>();
yield return new WaitForEndOfFrame();
toDestroy.transform.GetChild(0).gameObject.GetComponent<MeshExploder>().Explode();
yield return new WaitForEndOfFrame();
Destroy(toDestroy);
yield return new WaitForEndOfFrame();
}
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
//Debug.Log("Current scene index is : " + currentSceneIndex);
if (currentSceneIndex >= firstForestSceneIndexNumber && currentSceneIndex <= lastForestSceneIndexNumber)
{
// Start scene change countdown timer
forestSceneTimer.StartSceneCountTimer(sceneCountdownLength);
}
}
private IEnumerator DoInitSceneIndexList()
{
// Initialize scene name list
for (int i = 0; i < numberOfForestScenes; i++)
{
forestSceneIndexes.Add(firstForestSceneIndexNumber + i);
Debug.Log("Scene index " + forestSceneIndexes[i].ToString() + " added to int list.");
}
yield return new WaitForEndOfFrame();
initSceneList = false;
}
private IEnumerator DoInitForestGameManager()
{
if (fgm == null)
fgm = this;
else if (fgm != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
yield return new WaitForEndOfFrame();
}
private IEnumerator DoInitServerNetworking()
{
Instantiate(serverNetworkManagerPrefab);
yield return new WaitForEndOfFrame();
}
public void GetRandomScene()
{
Debug.Log("Get Random Scene");
StartCoroutine(DoGetRandomScene());
}
private IEnumerator DoGetRandomScene()
{
//Debug.Log("First forest scene index : " + firstForestSceneIndexNumber);
//Debug.Log("Last forest scene index : " + lastForestSceneIndexNumber);
// Get scene name from random pick
randomSceneIndex = Random.Range(firstForestSceneIndexNumber, (firstForestSceneIndexNumber + forestSceneIndexes.Count) - 1);
Debug.Log("First scene in list is " + firstForestSceneIndexNumber + " , the last one is " + ((firstForestSceneIndexNumber + forestSceneIndexes.Count) - 1));
yield return new WaitForEndOfFrame();
StartCoroutine(DoRemoveRandomSceneFromList());
// Load selected scene
StartCoroutine(DoLoadScene(randomSceneIndex));
Debug.Log("randomSceneIndex is " + randomSceneIndex);
for (int i = 0; i < forestSceneIndexes.Count; i++)
{
// Debug.Log("Scene " + forestSceneIndexes[i].ToString() + " is still left in the list");
Debug.Log(forestSceneIndexes.Count.ToString() + " scenes are still left in the list");
}
}
private IEnumerator DoRemoveRandomSceneFromList()
{
// Remove selected scene from list
forestSceneIndexes.Remove(randomSceneIndex);
Debug.Log("Scene " + randomSceneIndex + " has been removed from the list.");
yield return new WaitForEndOfFrame();
}
private IEnumerator DoLoadScene(int sceneIndex)
{
yield return new WaitForEndOfFrame();
SceneManager.LoadScene(sceneIndex, LoadSceneMode.Single);
foreach (ForestAnimal animal in forestAnimals) // Spawn Animal Stored in the forestAnimals List
{
// print("Animal " + animal.forestAnimalName + "is still in the list");
//GameObject animalGO = (GameObject)Instantiate(animal.forestAnimalGO);
//NetworkServer.Spawn(animalGO);
Debug.Log(animal.forestAnimalName + " re-instantiated in new scene");
}
}
}
答案 0 :(得分:1)
除了评论中提到的问题,您应该仔细检查,问题在于您如何选择随机数。你并没有从实际的指数列表中抽出来。它应该是这样的:
np.array
注意,我没有修改你对协同程序的大部分使用,但正如评论中所指出的那样,你肯定有很多需要清理的地方。