统一性:添加"Persistent-Scene"后,出现奇怪的场景转换错误与GameManager [英] Unity: Weird scene transition bug after adding a "Persistent-Scene" with a GameManager

查看:185
本文介绍了统一性:添加"Persistent-Scene"后,出现奇怪的场景转换错误与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆