如何基于Unity中的先前场景定位播放器

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

在本教程中,我将使用两个场景WorldInterior 。 如果需要设置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);
}

}

我们有两个静态字符串, prevScenecurrentScene

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有两个私有变量, toScenesceneController

这里的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中。

由于内部场景中只有一个入口点,因此我们将播放器和摄像机的位置默认设置为在门对象附近,因此无需创建脚本来更改位置。

设置好所有内容后,您应该得到如下所示的结果。