Evans Belloeil
Evans Belloeil

Reputation: 2503

Best way to move a networked Gameobject smoothly?

I've got an issue when I try to move smoothly a Gameobject.

I receive every second through a TCP Protocol a position, where my Gameobject have to move. So I have my start position, my end position, I can calculate the distance between the two position , and I know my Gameobject have to move with a constant speed to my end point in 1 second.

I try 3 solutions that are : Learp, MoveToward and SmoothDamp , but none of them work, my Gameobject just teleport from point A to point B every time.

Here's what I try in my code (my Gameobject is referenced in a dictionnary, my Gameobject are planes) :

// Distance between my 2 points
float step = Vector3.Distance(planeId_Object_Dictionnary[newPlane.Flight].transform.position, new Vector3((float)newPlane.X, (float)newPlane.Afl / (3.2808f * 1852f), (float)newPlane.Y));
//Use of Lerp
//planeId_Object_Dictionnary[newPlane.Flight].transform.position = Vector3.Lerp(planeId_Object_Dictionnary[newPlane.Flight].transform.position, new Vector3((float)newPlane.X, (float)newPlane.Afl / (3.2808f * 1852f), (float)newPlane.Y), step);
//Use of MoveTowards
planeId_Object_Dictionnary[newPlane.Flight].transform.position = Vector3.MoveTowards(planeId_Object_Dictionnary[newPlane.Flight].transform.position, new Vector3((float)newPlane.X, (float)newPlane.Afl / (3.2808f * 1852f), (float)newPlane.Y), step);
//Use of SmoothDamp
//planeId_Object_Dictionnary[newPlane.Flight].transform.position = Vector3.SmoothDamp(planeId_Object_Dictionnary[newPlane.Flight].transform.position, new Vector3((float)newPlane.X, (float)newPlane.Afl / (3.2808f * 1852f), (float)newPlane.Y), ref newPlane.GroundSpeed, 1);

The code is a function that is called in my Update this way :

void Update () {
        lock (threadLock)
        {
            // Message receive from my TCP Protocol
            while (q_orders.Count > 0)
            {
                switch (q_orders.Dequeue())
                {
                    case OrderType.trackmovedevent:
                        aircraftMajInfos(q_args.Dequeue()); // My function to move my Object
                        break;
                }
            }
        }
    }

Upvotes: 1

Views: 8123

Answers (3)

Mikael Larsson
Mikael Larsson

Reputation: 61

I would suggest the following:

  • Create a new script "ObjectMover" (maybe not the best name) and apply it on the Game Objects that you want to be able to move.
  • In the script create a public method: MoveToNewPos(Vector3 newPos) which stores the new position that you are aiming for with this object.

Inside the Update method of "ObjectMover" use lerp or calculate the stepping yourself using step / moveTime * Time.deltaTime to move towards the wanted new position and only adjust the speed to you desired look and feel.

From your "main" script do theObjectIWantToMove.GetComponent().MoveToNewPos(newPos); and it will smoothly move there.

Upvotes: 0

AminSojoudi
AminSojoudi

Reputation: 2016

Its better to use a tween engine , like http://dotween.demigiant.com/.

If you install Dotween then you can simply use

transform.DOMove(new vector3(1 ,0 , 1) , duration);

You can also set Ease for tweens. or use Oncomplete fucntions;

transform.DOMove(new vector3(1 ,0 , 1) , duration)
    .SetEase(Ease.OutCubic)
    .OnCompelete(() => { shouldClose = true; }); 

Upvotes: 4

DRKblade
DRKblade

Reputation: 347

I must say that you have understand all three functions totally wrong. They should be called in multiple updates, not just once.

In this situation I recommend MoveTowards. Because SmoothDamp doesn't move the object at a constant speed, and to use Lerp, you need to caltulate the ratio between the two points (note that you CAN move the object constantly if you add the amount to the t parameter every fixed update).

Here's a code snippet I wrote for the MonoBehaviour of your gameobject

const float moveTime = 1;
Vector3 target, step;

void Update () {
    transform.position = Vector3.MoveTowards(transform.position, target,
        step / moveTime * Time.deltaTime);
}
// Call this method to set the new target (the currently received position from network)
public void SetTarget (Vector3 positon) {
    target =  positon;
    step = Vector3.Distance(transform.position, target);
}

Time.deltaTime is the interval between updates (where the Update () function called)

Upvotes: 3

Related Questions