我做了一个非常基本的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()
被第二次调用时会发生奇怪的事情。
答案 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)吗?如果不是那么这可能是原因 - 您可以尝试使用附加模式加载场景,或者通过在正确的位置实例化场景加载的播放器。