2

get_gameObject can only be called from the main thread.

Is the error I am getting which I've figured out is to do with the way event handlers are implemented in C#.

In my Start method I have

EventManager.Instance.AddListener(EVENT_TYPE.UPDATE, this);

Then in my OnEvent handler method I have

public void OnEvent(EVENT_TYPE Event_Type, Component Sender, object Param=null)
{
    //Detect event type
    switch (Event_Type)
    {
        case EVENT_TYPE.UPDATE:
           Debug.Log(" UPDATE Timer event received Param = "+ Param);
            foo(Param as string);
            break;
    }
}

And then my foo method

private void foo(string param)
{
    Debug.Log("ASSERT foo gameObject" + gameObject);

So gameObject is null because the foo method is not on the main thread. So how DO I access gameObject then?

Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
Bachalo
  • 6,965
  • 27
  • 95
  • 189
  • I recently implemented an eventing system in my own Unity3d project using delegates. It allows you to run events in the context of where you want them to be fired. I can explain how that works which I believe would solve your problem, but it'd be an alternate solution, rather than a direct answer. – ChadF Jul 10 '15 at 19:46
  • What is `EventManager`? That doesn't look like something built into Unity? – Dave Carlile Jul 10 '15 at 21:21
  • Why are you off-thread in the first place? As Dave suggests, you should perhaps explain what your `EventManager` is. – Dan Puzey Jul 10 '15 at 22:28
  • Thanks ChadF. I guess I should look into a delegate solution instead. The EventManager class I am referencing from a recent book I purchased. I just googled and the actual class is viewable on google books as well. https://goo.gl/W3wgQZ – Bachalo Jul 11 '15 at 01:51
  • And just found one that uses delegates...will try this next! http://goo.gl/FOzebW – Bachalo Jul 11 '15 at 02:00

1 Answers1

0

As in every Windows applications, in Unity3D you have to access the elements only from Thread they were created (main thread, or UI thread generally), and the error message clearly states that this is your case.

So you can solve this by two ways:

  1. Use Loom helper class:

    Loom.QueueOnMainThread(() =>
    {
        Debug.Log("ASSERT foo gameObject" + gameObject);
    }); 
    

    or

    Loom.DispatchToMainThread(() =>
    {
        Debug.Log("ASSERT foo gameObject" + gameObject);
    }); 
    

    But in this case you have to initialize the Loom object, for example, add some useless code in Start method:

    void Start()
    {
        var tmp = Loom.Current;
        // or
        Loom.Current.GetComponent<Loom>(); // irrelevant call to kickoff Loom.        
    }
    
  2. Use Dispatcher class:

    Dispatcher.CurrentDispatcher.BeginInvoke(
      DispatcherPriority.Normal,
      () => { // your work here });
    
VMAtm
  • 27,943
  • 17
  • 79
  • 125