简体   繁体   中英

Best way to move my 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;
                }
            }
        }
    }

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; }); 

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM