统一性:添加"Persistent-Scene"后,出现奇怪的场景转换错误与GameManager [英] Unity: Weird scene transition bug after adding a "Persistent-Scene" with a GameManager
问题描述
我制作了一个非常基本的2D游戏来学习.我有2个Scenes
,在它们之间进行切换效果很好.我将空的gameObjects
用作Scene
的开始/退出点,这样游戏就可以知道在通过X点退出后将玩家放置在X点上(例如,如果我走出门,则离开房屋外).>
然后,我添加了一个"Scene0
",用于持久性通用脚本,如GameManager,声音,音乐等.我只有一个名为"Controller"的对象,我没有DontDestroyOnLoad().
添加此场景后,立即将Scenes
切换到我的MainScene,游戏突然开始表现得很奇怪.
第一次从MainScene(Scene1
)移到辅助场景(Scene2
)时,它可以正常工作,但是当我离开Scene2
返回到Scene1
时,玩家在茫茫荒野中生成.
而且只有当我从Persistent Scene
启动游戏时才会发生这种情况.
我不知道出什么问题了,我没有添加任何会干扰我的场景过渡的东西,到目前为止我只添加了用于测试的playerHealth.
附加到我的(持久)控制器的脚本:
DDOL:
public class DDOL : MonoBehaviour {
// Use this for initialization
void Awake () {
DontDestroyOnLoad (gameObject);
}
}
GameManager:
public class GameManager : MonoBehaviour {
public static GameManager manager;
public int playerMaxHealth;
public int playerCurrentHealth;
void Awake(){
if (manager == null) {
manager = this;
} else if (manager != this) {
Destroy (gameObject);
}
}
// Use this for initialization
void Start () {
SceneManager.LoadScene("test_scene");
}
// Update is called once per frame
void Update () {
}
}
附加到我的起点的脚本:
PlayerStartPoint:
public class PlayerStartPoint : MonoBehaviour {
private PlayerController thePlayer;
private CameraController theCamera;
public Vector2 startDir;
public string pointName;
// Use this for initialization
void Start () {
thePlayer = FindObjectOfType<PlayerController> ();
if (thePlayer.startPoint == pointName) {
thePlayer.transform.position = transform.position;
thePlayer.lastMove = startDir;
theCamera = FindObjectOfType<CameraController> ();
theCamera.transform.position = new Vector3(transform.position.x, transform.position.y, theCamera.transform.position.z);
}
}
}
最后是ExitPoint:
LoadNewArea:
public class LoadNewArea : MonoBehaviour {
public string levelToLoad;
public string exitPoint;
private PlayerController thePlayer;
// Use this for initialization
void Start () {
thePlayer = FindObjectOfType<PlayerController> ();
}
void OnTriggerEnter2D(Collider2D other){
if (other.gameObject.name == "Player")
{
SceneManager.LoadScene(levelToLoad);
thePlayer.startPoint = exitPoint;
}
}
}
将我所有的DDOL gameObject移到Pre-Scene之后,它就起作用了.因此,我可以假设故障出在Player或Cameras Start()
函数内部,因为当它们在Scene1中启动时,它们每次我进入场景时都会被调用(仅DDOL).
我尝试调整其Start()
功能,如下所示:
原始相机:
void Start () {
Debug.Log("Starting camera");
if (!cameraExists) {
cameraExists = true;
DontDestroyOnLoad (gameObject);}
else{
Destroy (gameObject);
}
}
更改相机:
void Start () {
DontDestroyOnLoad (gameObject);
}
在Player中进行了完全相同的更改.
显然,这是行不通的,因为它每次我输入Scene1时都会创建一个新的Camera/Player(顺便说一句,为什么我在输入Scene2时不尝试创建它们,是因为它们是从Scene1开始的?).但是,新的播放器/相机确实从正确的位置开始,如果缩小,我可以看到旧的播放器/相机在与以前相同的错误位置.因此,当他们的Start()
再次被调用时,就会发生一些奇怪的事情.
使用调试器.在相关位置(例如PlayerStartPoint.Start()
和LoadNewArea.OnTriggerEnter2D()
)设置断点,并检查它们是否已执行
- 在适当的时候
- 正确的次数
- 具有期望值
这应该使您了解事情失控的地方.
如果您使用Visual Studio,请安装 https://marketplace.visualstudio.com/items?itemName = SebastienLebreton.VisualStudio2015ToolsforUnity 以便能够在Visual Studio中调试Unity. 如果您不使用Visual Studio,则可能应该使用.
I made a pretty basic 2D game to learn. I have 2 Scenes
, and switching between them worked great. I used empty gameObjects
as Start/Exit point of the Scene
, so that the game would know to put player on point X after exiting through point X (for example exit outside house if I walk out the door).
Then I added a "Scene0
", to use for persistent general scripts like GameManager, Sounds, Music, etc. With just one object called "Controller" that I DontDestroyOnLoad().
After adding this Scene and then just switching Scenes
right away to my MainScene, all of a sudden the game starts acting really strange;
the first time I move from my MainScene (Scene1
), to my secondary Scene (Scene2
), it works fine, but then when I leave Scene2
to go back to Scene1
, the player spawns in the middle of nowhere.
And this ONLY happens if I launch the game from my Persistent Scene
.
I have no idea what is wrong, I don't add anything that interferes with my scene transitions, all I've added so far is playerHealth, for testing.
Scripts attached to my (persistent) Controller:
DDOL:
public class DDOL : MonoBehaviour {
// Use this for initialization
void Awake () {
DontDestroyOnLoad (gameObject);
}
}
GameManager:
public class GameManager : MonoBehaviour {
public static GameManager manager;
public int playerMaxHealth;
public int playerCurrentHealth;
void Awake(){
if (manager == null) {
manager = this;
} else if (manager != this) {
Destroy (gameObject);
}
}
// Use this for initialization
void Start () {
SceneManager.LoadScene("test_scene");
}
// Update is called once per frame
void Update () {
}
}
Scripts attached to my StartPoint:
PlayerStartPoint:
public class PlayerStartPoint : MonoBehaviour {
private PlayerController thePlayer;
private CameraController theCamera;
public Vector2 startDir;
public string pointName;
// Use this for initialization
void Start () {
thePlayer = FindObjectOfType<PlayerController> ();
if (thePlayer.startPoint == pointName) {
thePlayer.transform.position = transform.position;
thePlayer.lastMove = startDir;
theCamera = FindObjectOfType<CameraController> ();
theCamera.transform.position = new Vector3(transform.position.x, transform.position.y, theCamera.transform.position.z);
}
}
}
And finally ExitPoint:
LoadNewArea:
public class LoadNewArea : MonoBehaviour {
public string levelToLoad;
public string exitPoint;
private PlayerController thePlayer;
// Use this for initialization
void Start () {
thePlayer = FindObjectOfType<PlayerController> ();
}
void OnTriggerEnter2D(Collider2D other){
if (other.gameObject.name == "Player")
{
SceneManager.LoadScene(levelToLoad);
thePlayer.startPoint = exitPoint;
}
}
}
EDIT:
After moving all my DDOL gameObject to the Pre-Scene, it worked. So, I can assume the fault is inside Player or Cameras Start()
functions since when they start in Scene1 they get called every time I enter the Scene (only DDOL).
I tried adjusting their Start()
functions like follows:
Original camera:
void Start () {
Debug.Log("Starting camera");
if (!cameraExists) {
cameraExists = true;
DontDestroyOnLoad (gameObject);}
else{
Destroy (gameObject);
}
}
Changed Camera:
void Start () {
DontDestroyOnLoad (gameObject);
}
The exact same changes was made in Player.
Obviously this doesnt work because it creates a new Camera/Player every time I enter Scene1 (btw why does it not try to create them when I enter Scene2?, is it because they start in Scene1?). HOWEVER, the new player/camera do start at the correct position, and if I zoom out I can see the old player/camera at that same wrong position as before. So something weird happens when their Start()
is called a second time it seems.
Use the debugger. Have breakpoints at the relevant spots, like PlayerStartPoint.Start()
and LoadNewArea.OnTriggerEnter2D()
and check that they are executed
- At the right time
- The right number of times
- With the expected values
This should make you see where things get out of hand.
If you use Visual Studio, install https://marketplace.visualstudio.com/items?itemName=SebastienLebreton.VisualStudio2015ToolsforUnity to be able to debug Unity from within Visual Studio. If you are not using Visual Studio, you probably should.
这篇关于统一性:添加"Persistent-Scene"后,出现奇怪的场景转换错误与GameManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!