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

时间:2016-04-14 08:53:51

标签: c# unity3d unityscript unity5

当我尝试顺利移动Gameobject 时,我遇到了一个问题。

我通过TCP协议每秒接收一个位置,我的Gameobject必须移动。所以我有开始位置,我的结束位置,我可以计算两个位置之间的距离,我知道我的Gameobject必须移动在 1秒中以恒定的速度到达终点。

我尝试了3个解决方案: Learp MoveToward SmoothDamp ,但它们都不起作用,我的Gameobject只是从A点传送每次都指向B.

这是我在我的代码中尝试的内容(我的Gameobject在dictionnary中引用我的Gameobject是飞机):

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

代码是以我的更新方式调用的函数:

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

3 个答案:

答案 0 :(得分:3)

最好使用补间引擎,例如http://dotween.demigiant.com/

如果您安装了Dotween,那么您只需使用

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

您还可以为补间设置缓动。或使用Oncomplete fucntions;

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

答案 1 :(得分:2)

我必须说你已经完全理解了这三个功能。它们应该在多个更新中调用,而不仅仅是一次。

在这种情况下,我建议task-spooler。因为MoveTowards不能以恒定速度移动对象,并且要使用SmoothDamp,所以需要计算两点之间的比例(请注意,如果添加,可以不断移动对象)每次固定更新时t参数的数量。)

这是我为你的游戏对象的MonoBehaviour写的代码片段

Lerp

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函数的地方)

答案 2 :(得分:0)

我建议如下:

  • 创建一个新脚本“ObjectMover”(可能不是最佳名称)并将其应用于您希望能够移动的游戏对象。
  • 在脚本中创建一个公共方法:MoveToNewPos(Vector3 newPos),它存储您使用此对象瞄准的新位置。

在“ObjectMover”的Update方法中,使用lerp或使用step / moveTime * Time.deltaTime自行计算步进以移动到想要的新位置,并仅根据您想要的外观调整速度。

从“main”脚本执行ObjectIWantToMove.GetComponent()。MoveToNewPos(newPos);它会顺利地移动到那里。