本教程将介绍2D游戏中的定位,但也可以轻松应用于3D游戏。 我们将在两个或更多场景之间移动播放器。 在场景之间移动时,您可能会注意到播放器默认返回到其初始位置。 我们想要发生的是,当玩家穿过一扇门进入下一个场景,然后回到上一个场景时,玩家应该站在他们最初进入的同一扇门的外面。

在本教程中,我将使用两个场景World
和Interior
。 如果需要设置2D场景的帮助,建议您在Unity中研究如何创建图块。
我正在使用以下来源的图块集:
https://opengameart.org/content/orthographic-outdoor-tiles
https://opengameart.org/content/tiny-16-basic


我们有2个场景,但是现在我们需要一种在它们之间移动的方式。 我们要添加一个充当门的游戏对象。 在每个场景中,创建一个空的游戏对象,并将其命名为Door
。
您可以将此游戏对象保持为空,然后将其移动到显示为门的磁贴上,也可以向游戏对象添加门精灵。 在世界场景中,我把门当作瓷砖和空的游戏对象。 在室内,门物体是一个精灵。
在每个门对象上,在检查器中添加Box Collider 2D组件,然后选中Is Trigger 。 在size字段中,我通常使对撞机(门上的绿色框)比实际门小得多。 这样,玩家在更改场景之前会稍微在门上移动。

创建一个空的游戏对象,并将其命名为GameController
,还将标签更改为GameController。 我们将使用它来放置场景脚本。
创建一个新的C#脚本SceneController
并在下面插入代码。
使用UnityEngine;
使用UnityEngine.SceneManagement;
公共类SceneController:MonoBehaviour {
公共静态字符串prevScene =“”;
公共静态字符串currentScene =“”;
公共虚拟无效Start(){
//表示由场景脚本扩展/覆盖
currentScene = SceneManager.GetActiveScene()。name;
}
公共无效LoadScene(字符串sceneName){
prevScene = currentScene;
SceneManager.LoadScene(sceneName);
}
}
我们有两个静态字符串, prevScene
和currentScene
。
Start方法是一个虚拟方法,该方法设置我们的currentScene变量,并将允许我们的场景脚本扩展/覆盖此方法。
LoadScene方法在加载下一个场景之前设置prevScene变量。
将SceneController
脚本添加到我们的GameController对象中。
让我们创建另一个C#脚本ChangeScene
。
使用UnityEngine;公共类ChangeScene:MonoBehaviour {[SerializeField]私有字符串toScene;
私有SceneController sceneController; 无效Start(){
sceneController = GameObject.FindGameObjectWithTag(“ GameController”)。GetComponent ();
} private void OnTriggerEnter2D(Collider2D碰撞){
如果(collision.CompareTag(“ Player”)){
sceneController.LoadScene(toScene);
}
}}
ChangeScene有两个私有变量, toScene
和sceneController
。
这里的Start方法将sceneController变量设置为GameController对象上的SceneController组件。
OnTriggerEnter2D检查对象是否与门对象碰撞。 在这种情况下,我们要检查Player
的标签,并加载在toScene字段中设置的场景名称。
将ChangeScene
脚本添加到我们的门对象中。 在“检查器”选项卡中,输入要触发门加载的场景的名称。 在这种情况下,我们希望世界场景中的门能够进入室内,反之亦然。


该脚本将用于我们的世界场景,并将根据前一个场景设置播放器/相机的位置。
使用UnityEngine;
公共类世界:SceneController {
公共转换播放器;
//使用它进行初始化
公共替代无效Start(){
base.Start();
如果(prevScene ==“ Interior”){
player.position = new Vector2(0f,3f);
Camera.main.transform.position = new Vector3(0f,3f,-10f);
}
}
}
世界场景脚本从SceneController类派生而来,允许我们扩展/覆盖Start方法并访问prevScene变量。
通过将Player对象拖动到“检查器”选项卡中的字段中,可以设置player
的一个公共变量。
Start方法扩展了SceneController Start方法,因为我们在其中调用了base.Start()。 我们还检查prevScene是否等于“ Interior”,然后将播放器/摄像机位置设置在门对象附近。 您需要设置与场景设置相关的位置值。
如果您的场景包含许多“门对象”,我建议使用switch语句而不是if语句来检查prevScene值。
将World
脚本添加到我们的GameController中。
由于内部场景中只有一个入口点,因此我们将播放器和摄像机的位置默认设置为在门对象附近,因此无需创建脚本来更改位置。
设置好所有内容后,您应该得到如下所示的结果。
