- Home /
FSM: loading newScene before accesing newState
Hello everybody!:
Im using Unity free 4.3.4 in Mac. Codes is in C#.
My FSM is using a StateManager.cs and 4 states: BeginState, PlayState, WonState, LostSTate, all of them implementing IStateBase.
Problem explanation: The first state is BeginSTate in Scene0.(Main Menu). From BeginState.cs, when input is detected it should load Scene1 and THEN give control to PlayState. through StateManager.
PROBLEM: PlayState.cs constructor should use GameObject.find("ObjFromScene1") to get a reference to control a script from there. BUT when I debug.log(refObjFromScene1) it says NULL. It seams, Scene1 is loading while PlayState is already trying to acces constructor code.
I want to make sure Scene1 is fully loaded before calling NewState constructors! The whole purpose of this, was mainly to learn using FSM but Im kinda stuck on this. I tried using a coroutine on BeginState.cs but couldnt make it work.
This is StateManager.cs using UnityEngine; using Assets.Code.States; using Assets.Code.Interfaces;
public class StateManager : MonoBehaviour {
[HideInInspector]
public GameData gameDataRef;
private IStateBase activeState;
private static StateManager instanceRef;
void Awake()
{
if(instanceRef == null)
{
Debug.Log ("First time StateManager");
instanceRef=this;
DontDestroyOnLoad (gameObject);
}
else
{
DestroyImmediate(gameObject);
Debug.Log ("New instance destroyed GameManager");
}
}
void Start ()
{
activeState =new BeginState(this);
gameDataRef=GetComponent<GameData>();
Debug.Log("this object is of type "+activeState );
}
void Update () {
if(activeState!=null)
activeState.StateUpdate ();
}
void OnGUI()
{
if(activeState!=null)
activeState.ShowIt ();
}
public void SwitchState(IStateBase newState)
{
activeState=newState;
}
}
This is BeginState.cs using UnityEngine; using Assets.Code.Interfaces; using System.Collections; namespace Assets.Code.States { public class BeginState: IStateBase { private StateManager manager;
public BeginState(StateManager managerRef)//constructor
{
manager = managerRef;
if(Application.loadedLevelName != "BeginningScene")
Application.LoadLevel("BeginningScene");
Debug.Log ("Constructing BeginState");
//Time.timeScale=0;
}
public void StateUpdate(){}
public void ShowIt()
{
GUI.DrawTexture (new Rect(0,0,Screen.width,Screen.height),
manager.gameDataRef.beginStateSplash,
ScaleMode.StretchToFill);
if(GUI.Button (new Rect(10,10,250,60),"Press Here or Any Key to Continue")
|| Input.anyKeyDown)
{
Application.LoadLevel ("Scene1");//this keeps loading while already in PlayState!
manager.SwitchState (new PlayState(manager));
}
}
}
}
This is PlayState.cs using UnityEngine; using Assets.Code.Interfaces;
namespace Assets.Code.States
{
public class PlayState: IStateBase
{
private bool checkIfLevelIsLoaded=true;
private StateManager manager;
private GameObject token;
private Token tokenControllerScript;
#region Constructor!!!************************************
public PlayState(StateManager managerRef)//constructor
{
manager = managerRef;
Debug.Log ("Constructing PlayState");
planet= GameObject.Find ("Planet");
planetControllerScript=planet.GetComponent<PlanetController3>();
token= GameObject.Find ("Token");//this shows NULL
Debug.Log ("constructor:"+token);
tokenControllerScript=token.GetComponent<Token>();
}
#endregion Constructor!!!************************************
What should be my best approach to solve this?, I thought it was going to be easy because there are a few States, but cant go forward because of this. ONE SOLUTION was to make DontDestroyOnLoad("GameManager"), parent of this object(Token), as this script remains during all time, So the token remains while scene1 is still loading, token can be finded and referenced. BUT I dont want this GameManager to have so many children, and ALL being in State0. PLEASE ANY GUIDANCE IS WELCOME, Thank You, Alonso G.
Your answer
Follow this Question
Related Questions
How can I store and load levels efficiently? 2 Answers
scene loader issue 0 Answers
Importing 2D objects into Unity 5 Answers
If GameObject with tags not on scene 1 Answer
Storing in PlayerPref based on timer 1 Answer