Reputation: 10012
In Unity I have the following code in a script attached to a generic Game Object that has a Cube in it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
//using System.Runtime.Tasks;
public class ExampleScript : MonoBehaviour {
// Use this for initialization
void Start ()
{
Debug.Log ("Start():: Starting");
//SlowJob ();
Thread myThread = new Thread (SlowJob);
myThread.Start ();
Debug.Log ("Start():: Done");
}
// Update is called once per frame
void Update () {
//Option 1) This will move the cube in the application thread
//this.transform.Translate (Vector3.up * Time.deltaTime);
}
void SlowJob()
{
Debug.Log ("ExampleScript::SlowJob() --Doing 1000 things, each taking 2ms ");
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start ();
for (int i = 0; i < 1000; i++)
{
//Option 2) We are trying to move the cube in the secondary thread! ooops!!
//this.transform.Translate (Vector3.up * 0.002f);
//get_transform can only be called from the main thread
//Option 3) We are going to try to use a delegate on application thread
UnityEngine.WSA.Application.InvokeOnAppThread (()=>{
this.transform.Translate (Vector3.up * 0.002f);
},false);
//Option4
/* UnityEngine.WSA.Application.InvokeOnUIThread (()=>{
this.transform.Translate (Vector3.up * 0.002f);
},false);
*/
Thread.Sleep (2); //sleep for 2ms
}
sw.Stop ();
Debug.Log ("ExampleScript::SlowJob() --Done! Elapsed Time:" + sw.ElapsedMilliseconds / 1000f);
}
}
As you can see there is a SlowJob function that is executing on a different thread. Now, I want to update something in unity (the cube in this case) So I tried four things:
My question is why Option 3 does not work? I thought InvokeOnAppThread was used for these cases
(Just in case in SO there is only one other question regarding InvokeOnAppThread. Asked by me. And this is a different question so this is not a duplicate question)
My question is not on how to call unity stuff from another thread (although it solves that as well). My question is Why InvokeOnAppThread does not work for this?
I am aware there are convoluted ways to solve this. This is not what this question is about
I repeat This is not a duplicate question.
Any useful advice greatly appreciated
Upvotes: 0
Views: 1357
Reputation: 125455
My question is why Option 3 does not work? I thought InvokeOnAppThread was used for these cases
The InvokeOnAppThread
function is not used to make a call on Unity's main Thread from another Thread. It's is used to communicate between Unity and Windows App Thread. This function is used when making Windows App the native way with XAML then later decided to integrate Unity into this project. You can use it as a bridge to send message from the native side on the App main Thread to Unity or vice-versa. It's not meant to be called from another Thread
created by you, like you thought and like you are currently using it.
The InvokeOnAppThread
and InvokeOnUIThread
functions are poorly documented but to simplify them:
InvokeOnAppThread
- Used to invoke method from XAML to Unity.
InvokeOnUIThread
- Used to invoke method from Unity to XAML.
This is what is used to be in the past and hopefully, it is still have way. See Ref1 and Ref2 for examples.
Also, It's from the WSA
namespace and once you use it, you can't build your app for any other platform except for Windows platform. Your project won't build for Android, iOS, Mac and others.
Finally, you don't have a Windows XAML app you are communication with so you don't need InvokeOnAppThread
. Again, InvokeOnAppThread
is not used to communicate between your Thread and Unity's main Thread. It is used to communicate between Windows side of program made with XAML and Unity. You simply want to use Unity API in another Thread
. You either have to make your own function/wrapper to do that or use the one I already made from here.
Upvotes: 2