I am currently developing a 3D application using Unity. I am trying to get data from an eyetracker (Tobii x1) to have the position of the eyes in my Unity Scene. The good point is that it’s working. The drawback is that after that, I can still use unity but not closing it… Also, I am not able to run my application again.
I think I’ve found the line that makes everything going wrong:
browser = new EyeTrackerBrowser(EventThreadingOptions.CallingThread);
This constructor creates an EyeTrackerBrowser instance using the specific threading option for events.
I am not an expert with Unity, nor with C# language… I have tried many things but nothing seems to work :
Calling this ctor in the same thread as Unity in Update()
Using a different thread using Threads then close the thread when Unity is exiting.
Trying to use EventThreadingOptions.CallingThread or EventThreadingOptions.BackgroundThread in the two cases above.
The code is working in a simple C# console application. Do I have to manage my threads differently when using Unity ?
I have seen other people with my issue, but their solutions did not fix mine I read that Unity wasn’t Thread Safe, so I guess I’ve to be careful, but if I am not using UI things it’s ok right ?
Here are the simplified relevant parts of the code:
void Update () {
run();
}
void Start () {
Tobii.EyeTracking.IO.Library.Init();
}
void OnApplicationQuit(){
Terminate (); // When I try a separate thread, I ensure it's closed here.
}
private void run(){
if (browser == null)
{
browser = new EyeTrackerBrowser(EventThreadingOptions.CallingThread);
}
}
This is to hard to me, im not that good.
But when i failed a loop, and there is no stop in the loop.
Mine crashed. Maybe if you use some thing similar.
As I said previously in my comment, i guess the best option to simulate the using of Threads is using Coroutines.
A Couroutine is a function that will execute simultaneously, you define a function and call it using Coroutine functions. Follow up this example below:
public class WinglessAngel : MonoBehaviour
{
private bool hasWing;
private int wingDuration;
void Update()
{
if (GotWing())
{
if (hasWing)
StopCoroutine("DestroyWing");
hasWing = true;
StartCoroutine("DestroyWing");
}
}
IEnumerator DestroyWing()
{
yield return new WaitForSeconds(wingDuration);
hasWing = false;
}
}
My mind flew away for some time to think about this example, don’t know why i thought about that, but it is fine. You can write anything you want inside your Coroutine function, in this case, i just told it to wait for the wingDuration and then set hasWing to false.
Note that the GotWing() functions isn’t implemented, i just wrote it to simulate some collision verification or stuff like that.
I’m working at Tobii. The SDK shipped with the X1 eye tracker unfortunately has some threading issues that we know can cause problems with Unity. The good news is that we have developed two new SDK:s that are much more suitable for game development and Unity.
The Gaze SDK includes a low-level API for C/C++/C# that can be used to get raw gaze coordinates, similar to the SDK you are using today. In the EyeX SDK, we have also added some high-level behaviors that are very suitable for interaction. We have a Unity SDK package that includes some base classes to easily add eye interaction behaviors to Unity GameObjects. You can have a look at that package to see how we handled threading in Unity.
We are not sure how well the new SDK works on the X1 eye tracker, but you can give it a try. Otherwise, we have special price ($95) on the new eye trackers: http://www.tobii.com/en/eye-experience/buy/