Unity:在添加" Persistent-Scene"之后出现奇怪的场景转换错误用GameManager

时间:2017-05-31 11:31:54

标签: unity3d unity5

我做了一个非常基本的2D游戏来学习。我有2 Scenes,它们之间的切换效果很好。我使用空gameObjects作为Scene的开始/退出点,这样游戏就会知道在离开X点后将玩家放在X点上(例如我走出门外的房子出口) )。

然后我添加了一个" Scene0",用于持久的常规脚本,如GameManager,Sounds,Music等。只有一个名为" 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);
    }

}

游戏管理:

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 () {

    }
}

附加到我的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);
        }
    }
}

最后是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);
        }

在播放器中进行了完全相同的更改。 显然这不起作用,因为它每次进入Scene1时都会创建一个新的Camera / Player(顺便说一下,当我输入Scene2时它为什么不尝试创建它们?是因为它们是在Scene1中启动的吗?)。但是,新的播放器/摄像机确实从正确的位置开始,如果我缩小,我可以看到旧的播放器/摄像机处于与以前相同的错误位置。所以当他们Start()被第二次调用时会发生奇怪的事情。

3 个答案:

答案 0 :(得分:3)

您现在提到过您的代码是这样的,

void Start () {
        Debug.Log("Starting camera");
        if (!cameraExists) {
            cameraExists = true;
            DontDestroyOnLoad (gameObject);}
           else{
        Destroy (gameObject);
        }
    }

请注意,遗憾的是,这完全不正确&#34;,呵呵:)

你在问题​​中提到的问题(预加载场景等)与此处的问题完全无关。

在Unity中,如果在加载场景时场景a,b,c之间存在角色C,则必须在其自身(可能是空的)场景中启动C,你 不能 使用&#34; a&#34;为了方便起见C。

模式是,在a,b,c的每一个中,只有一行代码,如p = FindObjectOfType<Player>();,在场景加载时运行,而位置C则如你所愿。

现在,关于您正在看到的异常行为的特定难题

我知道你想知道为什么要观察你的行为。

这是对以下问题的混淆:1 - 觉醒和开始之间的区别,2 - 对脚本执行顺序的混淆 {但请参阅下面的 1 } 3 - 关于 Destroy vs. DestroyImmediate 的混淆4 - 不使用 Debug.Log ,而不是使用 gameObject.name 那里(它在Unity中很常见,在Debug.Log中对哪个对象进行了疯狂的混淆)5 - 你提到的时候你会看到另一个对象&#34;在旁边&#34;,它&#39;常见于彻底混淆哪一种在这种情况下是哪种情况6-计算机编程概念之间的混淆&#34;实例化&#34; (即,类或对象)和&#34; 实例化&#34; (令人困惑的是,它是同一个词 - 完全不相关的)游戏对象。

如果你摆弄所有这些问题,你会发现你所看到的行为的解释!

但它并不重要;在Unity中的&#34; C ... a b c&#34;例如,您必须事先单独创建C.

1 {另外,为了解决问题,不要在Unity中使用脚本执行排序系统;它仅用于R&amp; D目的;但实际上它可以帮助你调查这个问题中的行为,如果你特别想要完全理解为什么你会看到你明显看到的东西}

答案 1 :(得分:1)

使用调试器。在相关位置设置断点,例如PlayerStartPoint.Start()LoadNewArea.OnTriggerEnter2D(),并检查它们是否已执行

  • 在合适的时间
  • 正确的次数
  • 具有预期值

这可以让你看到事情失控的地方。

如果使用Visual Studio,请安装https://marketplace.visualstudio.com/items?itemName=SebastienLebreton.VisualStudio2015ToolsforUnity以便能够在Visual Studio中调试Unity。 如果您不使用Visual Studio,则可能应该这样做。

答案 2 :(得分:-2)

玩家在场景之间是否持久(他有DontDestroyOnLoad)吗?如果不是那么这可能是原因 - 您可以尝试使用附加模式加载场景,或者通过在正确的位置实例化场景加载的播放器。