- Home /
Wait for coroutine to finish before returning a value in another function
Hello, I know that this question has probably been asked a lot, I guess my problem could be quite different.. Let's say I've script A and script B. Script A creates a new instance of B's class which creates an object using asset bundle and coroutines. A then calls a bool function from B that checks if the object is not null and adds it to a list of objects to be able to do operations on them later. Due to the fact that StartCoroutine won't wait until it's finished, the bool function in B returns false the first time I click, and true the second time (Cause it wasn't done loading). Any helps?
Script A:-
public void addCollect(string name,string type , int x, int y)
{
if (!objects.ContainsKey(name))
{
CollectiveObject obj = new CollectiveObject(x, y, name, type);
if(obj.inti())
objects.Add(name, obj);
}
}
"obj.inti() returns false the first time and true the second time I try it out"
Script B:- I tried to load a dummy function first and have it wait for the asset loading to be done, but init() keeps executing anyway.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace RoboGarden
{
public class CollectiveObject : FieldObject
{
public CollectiveObject(int x, int y, string name,string type, float width = MainController.CELL_SIZE, float height = MainController.CELL_SIZE) : base(x, y, name, "collective", type, width, height)
{ }
public GameObject logo = GameObject.FindGameObjectWithTag("logo");
AssetBundleRequest request;
MonoBehaviour temp = GameObject.FindObjectOfType<MonoBehaviour>();
public IEnumerator ObjectCreator()
{
LoadingMenu myAssets = logo.GetComponent<LoadingMenu> ();
request = myAssets.wwwww.assetBundle.LoadAssetAsync (type + ".prefab", typeof(GameObject));
while(!request.isDone) {
yield return new WaitForSeconds (0.1f);
}
GameObject objj = request.asset as GameObject;
obj = GameObject.Instantiate (objj) as GameObject;
obj.transform.localScale = new Vector3 (MainController.SCALE * MainController.CELL_SIZE / realW, MainController.SCALE * MainController.CELL_SIZE / ((realW + realH) / 2), MainController.SCALE * MainController.CELL_SIZE / realH);
float X = (xIndex * MainController.SCALE * objectWidth) - (MainController.SCALE * objectWidth / 2);
float Y = (yIndex * MainController.SCALE * objectHeight) - (MainController.SCALE * objectHeight / 2);
obj.transform.position = new Vector3 (X, 0, Y);
obj.name = objectName;
yield return obj;
}
public IEnumerator DummyFunction()
{
yield return temp.StartCoroutine (ObjectCreator ());
}
public bool inti()
{
temp.StartCoroutine (DummyFunction ());
if (obj != null)
{
return true;
Debug.Log ("Found it inside indicator !");
}
else
{
return false;
HelperFunctions.consolePrint ("Not found");
}
}
}
}
My question is:- How can I have the init() function wait till the ObjectCreator gets done from instantiating the object, so if(obj.init()) returns true? Thanks in advance !
You could pass a callback function to the coroutine, for it to call when it's finished. You'd also have to split the init function into 2 parts - one for stuff that happens before the coroutine (and to call the coroutine) and one for the stuff that happens after the coroutine (this is the function you pass in as the callback).
Same technique I suggested in your previous question... http://answers.unity3d.com/questions/1236793/instantiated-object-from-asset-bundle-is-null.html, where you'll find some code explaining it further.
I tried to do it but it didn't work...the object instantiating function doesn't even work..maybe I misunderstood what you meant, here what I edited
public IEnumerator inti(System.Action<bool> callback)
{
yield return temp.StartCoroutine(ObjectCreator());
callback( obj != null );
}
and
public void addCollect(string name,string type , int x, int y)
{
if (!objects.Contains$$anonymous$$ey(name))
{
CollectiveObject obj = new CollectiveObject(x, y, name, type);
namez = name;
testObj = obj;
obj.inti (callbackfunction);
}
}
public void callbackfunction(bool b)
{
if (b) {
objects.Add (namez, testObj);
} else
Debug.Log ("Object not found");
}
What have I done wrong? Thanks in advance ^^
I fixed it, Thanks for putting me one the right track ^^ turned out I forgot to change obj.inti (callbackfunction); to temp.StartCoroutine(obj.inti (callbackfunction)); and just add
$$anonymous$$onoBehaviour temp = GameObject.FindObjectOfType<$$anonymous$$onoBehaviour>();
Your answer
Follow this Question
Related Questions
Instantiated object from asset bundle is null 0 Answers
StopAllCoroutines not working 0 Answers
Issue with nested coroutines getting stuck 1 Answer
Why doesnt my coroutine ever end? 2 Answers
Time Manager Class Implementation Like Coroutine in Unity 1 Answer