pusher / pusher-websocket-unity

Pusher Channels Unity Client Library
MIT License
27 stars 20 forks source link

GetComponent call inside Bind method results in a UnityException #27

Closed mauricioribeiro closed 3 years ago

mauricioribeiro commented 3 years ago

Hi guys,

I have the following code in my PusherManager:

channel.Bind("my-event", (dynamic data) =>
        {
               _myGameObject.GetComponent<Player>().DoSomething();
        }
});

Basically, I'm just trying to call a method from an attached GameObject in my PusherManager. But, since the code inside Bind method is async and it's using a different thread, the code throws this error:

GetComponentFastPath can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

I made some research and I think Unity blocks any GetComponent call inside parallel threads. Does anybody have any clue about how to solve this?

twomedia commented 3 years ago

We used this nice plugin on the asset store for dispatching to the MainThread: Task Parallel

Then in that Bind action you would do this:

UnityTask.RunOnUIThread(() => {
_myGameObject.GetComponent<Player>().DoSomething();
});

If you don't want to purchase that plugin, basically they are adding this action to a threadsafe queue which gets dequeued and invoked inside a MonoBehaviour Update() event.

mauricioribeiro commented 3 years ago

Thank you @twomedia. After some time, I managed to solve this by setting a boolean flag variable (like IsEventTriggered) on async Bind method to avoid get component on it.

So, in the async scope, I only set this flag to true instead call component DoSomething() and then in my not syncUpdate scope I verify this flag. If it's true, I finally call the componentDoSomething().

That was a workaround, but solved my problem. I think what I did is somehow similar to the plugin you recommended. Anyway, I will check it out :)