I have a working prototype of some base levels in a 2d top down Zelda type game. I’m having an issue with the overworld where a scene can have many entrances. I’m able to detect where the character is coming from and going to, but moving the player to the correct spawn point depending on the entrance is not working.
The SceneController detects a collision with the player and initiates a fade transition that loads the new scene. before I load the new scene i set the gamemanager variables.
GameManager.instance.PreviousScene = SceneManager.GetActiveScene().name;
GameManager.instance.CurrentScene = transform.name;
// using free fade asset from the store by FlatTutorials
FaderInit.Fade(transform.name, Color.black, 1.5f);
This all works great. Scenes load and fade in properly and i see that current and previous are being set properly. The only problem is that the character doesn’t appear in the correct spot. He always appears at the point where he was saved in the scene. i.e. 0,0,0. seems that player.transform.position isn’t doing anything here. I’m just wondering if i have some sort of ordering problem. i’ve tried it before the fade, in the middle and after…
i’m initiating this update by calling.
GameManager.instance.UpdateSpawnPoints();
yes, this will get ugly, and it’s hardcoded, but I’m just looking to get the behavior working before I break it out into an index, or configuration.
public class GameManager : MonoBehaviour
{
public static GameManager instance = null;
public string PreviousScene { get; set; }
public string CurrentScene { get; set; }
void Awake()
{
if (instance == null)
instance = this;
else if (instance != this)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
public void UpdateSpawnPoints()
{
if (CurrentScene.ToLower().CompareTo("grassland") == 0)
{
if (PreviousScene.ToLower().CompareTo("cavesouth") == 0)
{
player.transform.position = new Vector3(0f, -4.5f, 0f);
}
}
}
}
player is set properly and show in the inspector, it’s just not changing it’s transform. Any ideas?
How are you calling UpdateSpawnPoints? I mean, when you switch scenes, when do you make the call or from where?
I’m guessing also that your player is dontdestroyonload?
I was trying to set this on collision with the collider that triggers the scene change. I also tried to put it in the fader class, but you bring up a good point. I wasn’t keeping the player object around. I’m thinkin that’s part of the issue. Should I programmatically instantiate the character prefab if it’s null, and then persist it through the scenes?
public void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Player")
{
GameManager.instance.PreviousScene = SceneManager.GetActiveScene().name;
GameManager.instance.CurrentScene = transform.name;
FaderInit.Fade(transform.name, Color.black, 1.5f);
GameManager.instance.UpdateSpawnPoints();
}
}
It depends. For example, for me, I would probably store the vector3 in a variable, then when I switch scenes, I’d just have a script in the scene that would grab all values I need and have it setup the player for me with whatever data it needs.
As you have it, I’m not sure if you are actually switching scenes or simply have one big map that you’re trying to teleport around in. But if your player is colliding with a trigger that fades, then sets the players position, then loads the other scene, your player is being moved in the first scene and not when the new scene loads.
Also to add on, even if you try to target the player in the second scene, if that player is left behind in the first scene, you’ll likely get an error as the player gets destroyed when the first scene unloads.
Nice!
I put a playerSetup script on the player so that any scene with multiple entrances can be generically set.
basically on script start, query the GameManager to see where you are coming from and set the correct vector3 for that location. since this script loads via the Start() function, it happens when the character is created and before the fade.
I used something like this to get it working. Mainly my game will have only a couple of entrances for a given area and I wanted this to be reusable. by adding in a few more entrance sections, I can make this work for any scene. I put strings on there, just to make it easy to test out. I will probably make a better class for it in the long run but it’s working! thanks.
public class PlayerSetup : MonoBehaviour {
public string entrance1string;
public Vector3 entrance1vector;
public string entrance2string;
public Vector3 entrance2vector;
void Start ()
{
string cur = GameManager.instance.CurrentScene;
string prev = GameManager.instance.PreviousScene;
if (cur != null && prev != null)
{
if (prev.ToLower().CompareTo(entrance1string) == 0)
{
transform.position = entrance1vector;
}
else if (prev.ToLower().CompareTo(entrance2string) == 0)
{
transform.position = entrance2vector;
}
}
}