- Home /
StartCoroutine_Auto can only be called from the main thread.
Hi I'm having some problems with my code, I can assure that worked well, but now I jump with coroutines error ... Here is the code to see if anyone can help me ... I am using Ngui, then when you press a button called one of the coroutines, but now I get the error.
public IEnumerator WaitAlertView()
{
yield return new WaitForSeconds (0.2f);
EtceteraBinding.hideActivityView();
yield return new WaitForSeconds (0.6f);
EtceteraBinding.showAlertWithTitleMessageAndButton("Error","Es posible que el nombre de usuario ya exista, por favor escoge otro nombre","Vale");
}
public IEnumerator WaitAlertView2()
{
yield return new WaitForSeconds (0.2f);
EtceteraBinding.hideActivityView();
yield return new WaitForSeconds (0.6f);
EtceteraBinding.showAlertWithTitleMessageAndButton("Error","Se ha cancelado el registro","Vale");
}
public IEnumerator WaitAlertView3()
{
yield return new WaitForSeconds (0.2f);
EtceteraBinding.hideActivityView();
yield return new WaitForSeconds (0.6f);
EtceteraBinding.showAlertWithTitleMessageAndButton("Error","El Login ha fallado, comprueba que su usuario y password son correctos","Vale");
}
public IEnumerator WaitAlertView4()
{
yield return new WaitForSeconds (0.2f);
EtceteraBinding.hideActivityView();
yield return new WaitForSeconds (0.6f);
cargado = true;
}
// Update is called once per frame
public void Update ()
{
myName = nameuser.text;
myPassword = password.text;
myEmail = email.text;
loginUser2 = loginName.text;
loginPass2 = loginPass.text;
NivelCargado();
}
// Accion que se dispara cuando se pulsa el boton unirse a PLM
public void SendUserToParse()
{
EtceteraBinding.showBezelActivityViewWithLabel("Creando usuario, un momento por favor");
// Crear nuevo usuario en Base de datos
var user = new ParseUser()
{
Username = myName,
Password = myPassword,
Email= myEmail
};
Task signUpTask = user.SignUpAsync().ContinueWith(t =>
{
if (t.IsCanceled)
{
StartCoroutine(WaitAlertView2());
}
else if ( t.IsFaulted)
{
StartCoroutine(WaitAlertView());
}
else
{
StartCoroutine(WaitAlertView4());
}
});
}
// Accion que se dispara cuando se pulsa el boton Login
public void Login()
{
EtceteraBinding.showBezelActivityViewWithLabel("Conectando, un momento por favor");
ParseUser.LogInAsync(loginUser2,loginPass2).ContinueWith(t=>
{
if (t.IsFaulted || t.IsCanceled)
{
StartCoroutine(WaitAlertView3());
}
else
{
StartCoroutine(WaitAlertView4());
}
});
}
// Cuando el login se ha creado con exito cambiamos de escena
public void NivelCargado ()
{
if (cargado)
{
Application.LoadLevel ("EscenadeJuego");
}
}
Answer by Wolkenschauer · Feb 15, 2014 at 12:06 AM
well it sounds more like you're looking for a Invoke method with all the waiting to me, however if you want to start a coroutine from a different thread than the unity main thread, therefore you could create a list and add whatever the coroutine is supposed to do to it as for instance an action and invoke the action on a gameobject within the game loop (i use this kind of approach whenever i have network calls which are by nature asnchronious ...
1) create a gameobject in your scene and add a this script:
public class DoOnMainThread : MonoBehaviour {
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
public virtual void Update()
{
// dispatch stuff on main thread
while (ExecuteOnMainThread.Count > 0)
{
ExecuteOnMainThread.Dequeue().Invoke();
}
}
}
2) Add your coroutine action into the queue whenever you want to call it like this:
DoOnMainThread.ExecuteOnMainThread.Enqueue(() => { StartCoroutine(WaitAlertView4()); } );
it will be executed next opportunity the main thread can, or rather when the game object will call it's update method
After days of search this works perfectly for me. $$anonymous$$any thanks!
This needs to be the accepted answer. Very nice - especially for asynchronious execution such as networking as you mention!
Very good answer ! $$anonymous$$aybe it's obvious but in order to use Queue class you have to include:
using System.Collections.Generic;
Thank you very much, so helpful! But maybe there need queue data lock before ExecuteOn$$anonymous$$ainThread.Dequeue().Invoke();
?