我正在尝试创建一个管理器,它通过索引#从可能的索引列表中加载随机场景。一旦场景被加载,我想从列表中删除该项目,以消除相同的场景再次加载。一旦管理员完成了所有场景,我再次调用DoInitSceneIndexList()
来创建一个填充了场景的新列表,并且该过程将重新开始。除了一件事,一切都在这里工作。每当我切换场景时,列表将再次重建,并且它从完整列表开始,而不是每次减少一个。每次加载场景时,我在哪里制作重建列表的错误?谢谢!
ForestGameManager.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
public class ForestGameManager : MonoBehaviour
{
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;
[Header("Forest Scenes")]
[TextArea(1,1)]
public string forestSceneNotes = "Please place all Forest Scenes after Forest Loader scene";
public int numberOfForestScenes;
public float sceneCountdownLength;
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()
{
StartCoroutine(DoInitForestGameManager());
StartCoroutine(DoInitServerNetworking());
fgmIndex = SceneManager.GetActiveScene().buildIndex;
firstForestSceneIndexNumber = fgmIndex + 1;
Debug.Log("firstForestSceneIndexNumber Index is : " + firstForestSceneIndexNumber);
forestSceneTimer = GetComponent<ForestSceneTimer>();
}
private void Start()
{
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.");
}
private void Update()
{
// Destroy oldest animal gameobject based on maxAnimalCount
if (forestAnimals.Count >= maxAnimalCount)
{
GameObject toDestroy = forestAnimals[0].forestAnimalGO;
forestAnimals.RemoveAt(0);
Destroy(toDestroy);
}
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.");
}
}
}
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()
{
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, lastForestSceneIndexNumber);
yield return new WaitForEndOfFrame();
StartCoroutine(DoRemoveRandomSceneFromList());
// Load selected scene
StartCoroutine(DoLoadScene(randomSceneIndex, 0.0f));
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");
}
}
private IEnumerator DoRemoveRandomSceneFromList()
{
// Remove selected scene from list
forestSceneIndexes.Remove(randomSceneIndex);
yield return new WaitForEndOfFrame();
}
private IEnumerator DoLoadScene(int sceneIndex, float loadDelay)
{
yield return new WaitForSeconds(loadDelay);
SceneManager.LoadScene(sceneIndex, LoadSceneMode.Single);
}
}
ForestSceneTimer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ForestSceneTimer : MonoBehaviour
{
public static ForestSceneTimer fst = null; // create singleton
private IEnumerator _counter;
private void Awake()
{
InitRestartTimer();
}
void InitRestartTimer()
{
if (fst == null)
fst = this;
else if (fst != null)
Destroy(gameObject);
}
public void StartSceneCountTimer(float length)
{
//ForestGameManager.fgm.DestroyRestartTimer = false;
Debug.Log("Scene Timer Started");
_counter = RunTimer(length); // create new reference to counter, resets countdown to countdownLength
StartCoroutine(_counter);
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > 0)
{
yield return new WaitForSeconds(1);
//if (RestartDialogBoxInstance != null)
//_restartDialogCountdownTextTarget.text = s.ToString();
s -= 1;
if (s <= 0)
ForestGameManager.fgm.GetRandomScene();
Debug.Log(s);
}
}
}
答案 0 :(得分:0)
为了防止每次重建List,您必须做两件事。
将以下调用添加到 ForestGameManager 的Awake()方法中。
DontDestroyOnLoad(this.gameObject);
这样你的对象就不会在SceneChange上被销毁了。并保持直到你摧毁它或结束游戏。
使用bool检查您的GameManager是否已全部初始化
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
}
}