我正在尝试保存/加载我的游戏。在load方法中,每次我更改GameObject的属性时,都会应用这些更改,然后在不久后将其还原。这是我的代码:
public void Load()
{
SceneManager.LoadScene(sceneID);
List<GameObject> rootObjects = new List<GameObject>();
Scene scene = SceneManager.GetActiveScene();
scene.GetRootGameObjects(rootObjects);
int ncube = 0, npick = 0;
for (int i = 0; i < rootObjects.Count; ++i)
{
GameObject obj = rootObjects[i];
if (obj.CompareTag("Player"))
{
obj.transform.position = player.position;
obj.transform.rotation = player.rotation;
obj.transform.localScale = player.localScale;
}
else if (obj.CompareTag("Cube"))
{
obj.transform.position = cube[ncube].position;
obj.transform.rotation = cube[ncube].rotation;
obj.transform.localScale = cube[ncube].localScale;
++ncube;
}
else if (obj.CompareTag("Pickup"))
obj.SetActive(pickup[npick++]);
else if (obj.CompareTag("Door"))
obj.SetActive(door);
else if (obj.CompareTag("GreenWall"))
obj.SetActive(greenWall);
}
}
这些更改将应用于GameObject,但是它们会立即中止。我该如何解决?
脚本包含的这些代码行不是GameObject的组件。
编辑1:已更新完整代码。
答案 0 :(得分:4)
问题是我认为
Scene scene = SceneManager.GetActiveScene();
scene.GetRootGameObjects(rootObjects);
在场景完全加载之前从场景中获取对象,以便对其进行重置。
从Docu
使用SceneManager.LoadScene时,加载不会立即发生,而是在下一帧中完成。这种半异步行为可能会导致帧停顿,并且由于负载无法立即完成而令人困惑。
我想您宁可使用SceneManager.sceneLoaded并在其中进行操作
public void Load()
{
SceneManager.LoadScene(sceneID);
}
也许是场景中的一个额外组成部分:
void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// your stuff here
}
void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
尽管我们不知道/看不出player
,cube[ncube]
等的来源...
要在场景之间转换值,您应该使用ScriptableObjects
答案 1 :(得分:2)
问题可能是SceneManager.LoadScene
在下一帧中完成。请参阅文档:https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html
它说:
使用SceneManager.LoadScene时,不会发生加载 立即,它将在下一帧中完成。这是半异步的 行为可能会导致帧卡顿,并且由于负载而可能造成混乱 不能立即完成。
您在同一帧中更改值,因此在加载场景完成时它们将被覆盖。 Cou可以使用一个事件来阻止该行为:https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager-sceneLoaded.html