Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Calculate Vector3 distance and lerp in separate thread

Discussion in 'Scripting' started by Vedrit, Aug 16, 2016.

  1. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Hi all,
    I've been looking into putting Vector3 distance and lerp calculations in separate processing threads because I expect these to be done on hundreds of objects every frame, in addition to actually moving the object to the calculated lerp position, and so I expect that it'll be a problem when lumped in with everything else going on in the main thread.
    I haven't tested this, just researching at this point, and wondered if the following script would work, and how safe it would be.
    Code (csharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Threading;
    4.  
    5. class moveObject : MonoBehaviour
    6. {
    7.      public Vector3 moveTo;
    8.      public Vector3 _destination;
    9.      public bool updated;
    10.      private Object locker = new Object();
    11.  
    12.      void Update()
    13.      {
    14.           transform.position = moveTo;
    15.           if(updated)
    16.           {
    17.                Thread calc = new Thread(calcMove);
    18.                calc.Start();
    19.           }
    20.      }
    21.  
    22.      void calcMove()
    23.      {
    24.           updated = false;
    25.           lock(locker)
    26.           {
    27.                while(Vector3.Distance(transform.position, _destination) > 0.5f)
    28.                {
    29.                     moveTo = Vector3.Lerp(transform.position, _destination, 0.1f);
    30.                }
    31.           }
    32.      }
    33. }
    The _destination and updated variables would be set by another script which is managing all these other objects.

    Edit: I added a lock, just in case another update is added. I didn't want there to be moveTo that goes back and forth. I'm not sure that the lock is in a good spot, though. Would another bool be a better idea for the if conditions in Update?
     
    Last edited: Aug 16, 2016
  2. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    You have a race condition when updating moveTo on the thread. It may be partially updated while being accessed from the main thread. You have to synchronize access to values that aren't atomic.

    You have a race condition when changing/accessing the updated field. It may be possible for two or more threads to be created before updated gets set back to false.

    The while loop in your thread is running all out. By the time your Update method gets the position it's most likely already set to the final value.

    Starting up a thread is relatively expensive. Any gains (and there probably aren't any) to be had by calculating all of these things in a separate thread are going to be more than offset by creating a new thread in Update whenever something changes.

    You don't understand how threads work well enough to attempt something like this. Stay away from them.

    You should profile the application first and only optimize something like this if there is an actual performance problem.
     
  3. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    If I can prevent multiple threads from being created, would that resolve the race conditions of the first 2 points?
    I think the while loop is safe, since it takes the object's current position, which doesn't change until Update moves it, and changes the moveTo to 10% between current position and the destination. Though I may want to put in some sort of delay to prevent wasted calculation time.
    How might I go about setting up a single thread where all these other objects do their calculation? Then Unity won't be trying to set up hundreds of threads. Would it be via a singleton?

    So, what you're saying is, don't learn because you don't know? Don't get experience because you don't have experience?
     
    Propagant likes this.
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Note that you can't access the Unity API outside of the main thread, so this won't work at all.

    --Eric
     
  5. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Drat. Back to the drawing board.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    In any case you could improve performance by using better code rather than complicating things with threads, such as using sqrMagnitude rather than Vector3.Distance (so you'd avoid doing square roots).

    --Eric
     
  7. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Thanks for the suggestion. I am using Vector3.Distance a lot, in a lot of places, so sqrMagnitude would probably make a big difference
     
  8. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    No, it won't. Threads run concurrently and can be interrupted at any time. You need to synchronize access to shared data.

    No, by all means learn about writing threads and everything else you're hungry to learn about. All I'm saying that they are one of those difficult programming things to get right, and even programmers who have been using them for years can mess things up, and they can be very difficult to debug. Learning all of those things in the context of developing a game will most likely lead to hours and hours of frustration.

    And if your motivation is to optimize something that you haven't tested to see if it even needs optimization, then threads aren't the answer your looking for. I could and should have been more diplomatic in how I said that.

    I'm fairly certain the vector operations would be thread safe if operating on standalone Vector variables. But yes, accessing transform.position would be a problem.
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Indeed transform.position is what I was referring to.

    --Eric