简体   繁体   English

平稳移动我的Gameobject的最佳方法?

[英]Best way to move my Gameobject smoothly?

I've got an issue when I try to move smoothly a Gameobject . 尝试平滑移动Gameobject时遇到问题

I receive every second through a TCP Protocol a position, where my Gameobject have to move. 每秒通过TCP协议收到一个位置,我的游戏对象必须移动到该位置。 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 . 所以我有我的起始位置终点位置 ,我可以计算两个位置之间的距离 ,我知道我的游戏对象必须以恒定的速度移动到我的终点1秒

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. 我尝试了3个解决方案: LearpMoveTowardSmoothDamp ,但是它们都不起作用,我的Gameobject每次每次都从A点传送到B点。

Here's what I try in my code ( my Gameobject is referenced in a dictionnary , my Gameobject are planes ) : 这是我在代码中尝试的内容( 字典中引用了 我的Gameobject我的Gameobject是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 : 该代码是在我的Update中以这种方式调用的函数:

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/ . 最好使用补间引擎,例如http://dotween.demigiant.com/

If you install Dotween then you can simply use 如果您安装Dotween,则只需使用

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 . 在这种情况下,我建议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). 因为SmoothDamp不能以恒定的速度移动对象,并且要使用Lerp ,您需要计算两点之间的比率(请注意,如果在每次固定更新时将量添加到t参数中,都可以不断移动对象) 。

Here's a code snippet I wrote for the MonoBehaviour of your gameobject 这是我为您的游戏对象的MonoBehaviour编写的代码段

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) Time.deltaTimeTime.deltaTime更新之间的间隔(其中调用了Update ()函数)

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. 创建一个新的脚本“ ObjectMover”(可能不是最好的名称),并将其应用到您希望移动的游戏对象上。
  • In the script create a public method: MoveToNewPos(Vector3 newPos) which stores the new position that you are aiming for with this object. 在脚本中,创建一个公共方法:MoveToNewPos(Vector3 newPos),该方法存储您要使用此对象定位的新位置。

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. 在“ ObjectMover”的Update方法中,使用lerp或使用step / moveTime * Time.deltaTime计算自己的步进,以移至所需的新位置,并仅根据所需的外观调整速度。

From your "main" script do theObjectIWantToMove.GetComponent().MoveToNewPos(newPos); 从您的“主要”脚本中执行ObjectIWantToMove.GetComponent()。MoveToNewPos(newPos); and it will smoothly move there. 它将平稳地移动到那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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