Reputation: 27
In Unity I have GameObjectName which has script 1 and script 2 attached to it. Script1 is an IEnumerator like this.
public IEnumerator Sunglasses()
{
// Do stuff
}
Script2 looks like this.
public void Start()
{
Function1();
String blah = "Things";
Function2();
StartCoroutine(Routine2());
StartCoroutine(Routine3());
}
I need script 1 to finish Sunglasses before script 2 does anything. If I try accessing GameObjectName.Script1 from Script2, Unity says it doesn't exist. How can I make sure that script 1 finishes before starting script 2?
Upvotes: 0
Views: 6048
Reputation: 125435
You can add a boolean variable in script one, after the Sunglasses
function call is done, set it to true
.
Script1:
public bool isDone = false;
public IEnumerator Sunglasses()
{
// Do stuff
isDone = true;
}
Script2:
Then in your Script2, you can make your Start
function to be a coroutine or IEnumerator
instead of a void
function. After this, you can wait for isDone
to be true every frame.
public bool isDone;
Script1 script1Ref;
public IEnumerator Start()
{
GameObject s1Obj = GameObject.Find("GameObjectScript1IsAttachedTo");
script1Ref = s1Obj.GetComponent<Script1>();
//Wait here until we are done
while (!script1Ref.isDone)
yield return null;
//Done Waiting, now continue with the rest of the code
Function1();
String blah = "Things";
Function2();
StartCoroutine(Routine2());
StartCoroutine(Routine3());
}
Finally, if you also need to make sure that Script1 is dine before doing something in the Update
function of Script2, just check the isDone
variable and return if it it still false
.
void Update()
{
//Return if script 1 is not done
if (!script1Ref.isDone)
return;
//The rest of your code below
}
Note that you want StartCoroutine(Routine3())
to wait until StartCoroutine(Routine2())
is done, you have to yield it.
Replace StartCoroutine(Routine3())
with yield return StartCoroutine(Routine3())
.
Upvotes: 2
Reputation: 551
You can try studying events, or observer pattern. What I have been using is the latter which allows me to add callbacks with a string identifier. For events, you do something like
public static event System.Action onSunglassesCompleted;
public IEnumerator Sunglasses()
{
//Sunglasses logic here
//if there is a listener to the event, call it
if(onSunglassesCompleted != null)
{
onSunglassesCompleted();
}
}
Then on Script2, you just have to add the listener to the event
void Start()
{
Script1.onSunglassesCompleted += DoThisAfterSunglasses;
}
//This will be called in Script1
void DoThisAfterSunglasses()
{
//Make sure you do this to avoid memory leaks or missing reference errors once Sprite1 is destroyed
Script1.onSunglassesCompleted -= DoThisAfterSunglasses;
Function1();
String blah = "Things";
Function2();
StartCoroutine(Routine2());
StartCoroutine(Routine3());
}
One thing you can do in events to avoid leaks is by setting it to null after you call it.
if(onSunglassesCompleted != null)
{
onSunglassesCompleted();
onSunglassesCompleted = null;
}
Upvotes: 1