C# 平滑移动游戏对象的最佳方法?

C# 平滑移动游戏对象的最佳方法?,c#,unity3d,unityscript,unity5,C#,Unity3d,Unityscript,Unity5,我在尝试平滑移动游戏对象时遇到了一个问题 我通过TCP协议每秒接收一个位置,我的游戏对象必须在这个位置移动。因此我有我的开始位置,我的结束位置,我可以计算两个位置之间的距离,我知道我的游戏对象必须在1秒内以恒定速度移动到我的终点 我尝试了三种解决方案:Learp、MoveToward和SmoothDamp,但都不起作用,我的游戏对象每次都只是从A点传送到B点 以下是我在代码中尝试的内容(我的游戏对象在字典中引用,我的游戏对象是平面): 代码是一个函数,在我的更新中以以下方式调用: void Up

我在尝试平滑移动游戏对象时遇到了一个问题

我通过TCP协议每秒接收一个位置,我的游戏对象必须在这个位置移动。因此我有我的开始位置,我的结束位置,我可以计算两个位置之间的距离,我知道我的游戏对象必须在1秒内以恒定速度移动到我的终点

我尝试了三种解决方案:LearpMoveTowardSmoothDamp,但都不起作用,我的游戏对象每次都只是从A点传送到B点

以下是我在代码中尝试的内容(我的游戏对象在字典中引用,我的游戏对象是平面):

代码是一个函数,在我的更新中以以下方式调用:

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

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

在这种情况下,我建议
移动。由于
SmoothDamp
不会以恒定速度移动对象,并且要使用
Lerp
,需要计算两点之间的比率(请注意,如果每次固定更新都将量添加到t参数,则可以不断移动对象)

下面是我为游戏对象的单一行为编写的代码片段

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

我必须说,您对这三个函数的理解完全错误。它们应该在多个更新中调用,而不是一次

在这种情况下,我建议
移动。由于
SmoothDamp
不会以恒定速度移动对象,并且要使用
Lerp
,需要计算两点之间的比率(请注意,如果每次固定更新都将量添加到t参数,则可以不断移动对象)

下面是我为游戏对象的单一行为编写的代码片段

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

最好使用tween引擎,如

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

transform.DOMove(new vector3(1 ,0 , 1) , duration);
您还可以为青少年设置轻松。或使用完整的功能

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

最好使用两个引擎,比如

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

transform.DOMove(new vector3(1 ,0 , 1) , duration);
您还可以为青少年设置轻松。或使用完整的功能

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

我建议如下:

  • 创建一个新脚本“ObjectMover”(可能不是最好的名称),并将其应用到您希望能够移动的游戏对象上
  • 在脚本中,创建一个公共方法:MoveToNewPos(Vector3 newPos),该方法存储您使用此对象瞄准的新位置
在“ObjectMover”的更新方法中,使用lerp或使用step/moveTime*Time.deltaTime自行计算步长,以移动到所需的新位置,并仅根据所需的外观和感觉调整速度


从“主”脚本中执行ObjectIwantToMove.GetComponent().MoveToNewPos(newPos);它将平稳地移动到那里。

我建议如下:

  • 创建一个新脚本“ObjectMover”(可能不是最好的名称),并将其应用到您希望能够移动的游戏对象上
  • 在脚本中,创建一个公共方法:MoveToNewPos(Vector3 newPos),该方法存储您使用此对象瞄准的新位置
在“ObjectMover”的更新方法中,使用lerp或使用step/moveTime*Time.deltaTime自行计算步长,以移动到所需的新位置,并仅根据所需的外观和感觉调整速度


从“主”脚本中执行ObjectIwantToMove.GetComponent().MoveToNewPos(newPos);它将平稳地移动到那里。

是否在Update()或任何其他循环中调用MoveToward?是的,我在更新中调用它。在Lerp和SmoothDamp的最后一个参数中使用较低的值。Lerp的工作方式是取A点和B点,然后查看最终参数中的值S并返回C点。基本上S表示A和B之间的标准化值,这意味着S=0返回A,S=1返回B,S=0.5返回A和B之间的中点,依此类推。。。换句话说,距离(A,C)和距离(B,C)的比值等于S和(1-S)的比值。因此,在您的情况下,使s1始终返回目的地,导致“传送”。使该值小于1。此外,要使Lerp帧速率独立,u只需将S值乘以Time.deltaTime即可。因此,以60帧/秒的速度玩游戏的人不会比以30帧/秒的速度玩游戏的人有更快的转换速度。使用此解决方案,我如何确保在1秒内从a点到B点?我尝试将第三个参数设置为0.1*Time.deltaTime,但它移动非常缓慢且不平稳:(您是否在Update()中调用MoveTowards)或者任何其他循环?是的,我在更新中调用它。在Lerp和SmoothDamp的最后一个参数中使用较低的值。Lerp的工作方式是取点A和点B,然后它查看最终参数中的值S并返回点C。基本上S表示A和B之间的标准化值,即S=0返回A,S=1返回B,S=0.5返回中间值在A和B之间的点等等…换句话说,距离(A,C)和距离(B,C)的比率等于S和(1-S)的比率。所以在你的情况下,使S1总是返回目的地,导致“传送”。使该值小于1。此外,要使Lerp帧速率独立,u只需将S值乘以Time.deltaTime。这样,以60fps播放的家伙的转换速度不会比以30fps播放的家伙快。使用此解决方案,我如何确保在1秒内从a点到B点?我尝试将第三个参数设置为0.1*时间。deltaTime,它移动得很慢而且不平稳:(好了,现在我明白了为什么我的目标是telepo