Reputation: 43
This is the code I have for my spawner object on the level scene:
public float spawnShipID;
public GameObject basicShip;
void Start()
{
if (spawnShipID == 1)
{
Instantiate(basicShip, transform.position, Quaternion.identity);
}
}
And this is the code I have on a button on the start menu:
public float ShipID = 1f;
public void shipchoice()
{
SceneManager.LoadScene("watcherqueen");
GameObject.Find("playerspawner").GetComponent<spawnplayer>().spawnShipID = ShipID;
}
The reason I am using different floats on the button and the spawner is because I would like to have different buttons spawn different ships.
Using this code, the scene changes (only with the Play button, but not in the build, though that is a question for another time), and the player ship does not spawn. Are there any solutions or better ways I could have done this?
Upvotes: 0
Views: 43
Reputation: 20270
When you call LoadScene
, the scene does not fully load until the next frame. Therefore, your GameObject.Find("playerspawner")
doesn't even find the instance of playerspawner that is in that scene. (And, even if it were the same instance, it wouldn't run through its Start
again.)
Instead, you should set the variable to something that already exists in the scene currently running, which also will not destroy on load. A Singleton is especially useful for this application. Starting from this example by PearsonArtPhoto:
public class ShipSingleton: MonoBehaviour {
private static ShipSingleton _instance;
public static ShipSingleton Instance { get { return _instance; } }
private void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(this.gameObject);
} else {
_instance = this;
DontDestroyOnLoad(this.gameObject);
}
}
public int spawnShipID;
}
Then in the start menu button:
public int ShipID = 1f;
public void shipchoice()
{
SceneManager.LoadScene("watcherqueen");
ShipSingleton.Instance.spawnShipID = ShipID;
}
and in the spawner:
public GameObject basicShip;
void Start()
{
if (ShipSingleton.Instance.spawnShipID == 1)
{
Instantiate(basicShip, transform.position, Quaternion.identity);
}
}
I used an int for spawnShipID for simplicity, but an enum
would be better practice, including how it could help avoid entering invalid ids.
Using an enum could look something like this:
public class ShipSingleton: MonoBehaviour {
private static ShipSingleton _instance;
public static ShipSingleton Instance { get { return _instance; } }
private void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(this.gameObject);
} else {
_instance = this;
DontDestroyOnLoad(this.gameObject);
}
}
public enum ShipType
{
small,
medium,
large,
boss
};
public ShipType spawnShipID;
}
Then in the start menu button:
public ShipSingleton.ShipType ShipID = ShipSingleton.ShipType.small;
public void shipchoice()
{
SceneManager.LoadScene("watcherqueen");
ShipSingleton.Instance.spawnShipID = ShipID;
}
and in the spawner:
public GameObject basicShip;
void Start()
{
if (ShipSingleton.Instance.spawnShipID == ShipSingleton.ShipType.small)
{
Instantiate(basicShip, transform.position, Quaternion.identity);
}
}
Upvotes: 1