Unity3d Unity在一定的秒数内将对象移动到一个点(变换)

Unity3d Unity在一定的秒数内将对象移动到一个点(变换),unity3d,transform,Unity3d,Transform,我想让物体在几秒钟内改变它的位置。例如,它将在5秒内“到达”一个点 选择一个位置并在固定的时间内到达它。有可能吗?它有功能吗 Lat示例。我的目标在(10f,10f,0)我希望他在2秒内到达(20f,10f,0) 可能吗 更新:例如,在scratch中,它被称为“滑翔10,78秒到3秒”——在3秒内移动到10倍,78秒到3秒 有很多方法可以在统一中实现这一点 我将假设您正在进行3D体验并使用刚体组件 FixeUpdate是Unity每20毫秒调用一次的特殊方法—无论渲染或性能如何—这样您就可以可

我想让物体在几秒钟内改变它的位置。例如,它将在5秒内“到达”一个点

选择一个位置并在固定的时间内到达它。有可能吗?它有功能吗

Lat示例。我的目标在
(10f,10f,0)
我希望他在2秒内到达
(20f,10f,0)

可能吗

更新:例如,在scratch中,它被称为“滑翔10,78秒到3秒”——在3秒内移动到10倍,78秒到3秒

有很多方法可以在统一中实现这一点

我将假设您正在进行3D体验并使用刚体组件

FixeUpdate是Unity每20毫秒调用一次的特殊方法—无论渲染或性能如何—这样您就可以可靠、顺利地进行物理模拟

还记得经典公式吗:速率*时间=距离

private void UpdateRigidBody()
{
    Vector3 targetDestination = Vector3.MoveTowards(transform.position, destination, speed * Time.deltaTime);

    var rb = transform.GetComponent<Rigidbody>();
    rb.MovePosition(destination);
}
所以,在游戏控制逻辑的某个地方,你可以调用ChaseTarget并给它一个目标(矢量3)和到达目标的时间。您可以在对象上设置这些成员变量(targetDestination和speed),UpdaterGidBody函数将使您顺利到达目标

通常,当您离目标足够近时,您会执行某种新的游戏逻辑,然后重置目标目的地(UpdateRigidBody内:

    var destXZ = destination;
    var posXZ = transform.position;

    var dir = destXZ - posXZ;
    var arrived = dir.magnitude < arrivedRadiusMagnitude;
    if (arrived) // If I have arrived
    {
        Arrived();
    }
var destXZ=目的地;
var posXZ=变换位置;
var dir=destXZ-posXZ;
var arrived=方向震级

arrivedRadiusMagnitude是一个游戏设计问题,即某个东西在被认为到达之前能离目标有多近?例如,某种跟踪导弹在接近目标时可能会爆炸,而不一定正好在目标上方。

给你一个大致的概念:

public class MoveToTarget : MonoBehaviour
{
    public Transform target;
    public float duration;

    float distance;
    float t;
    private void Start()
    {
         distance = Vector3.Distance(transform.position, target.position);
    }
    private void Update()
    {
      
        transform.position = Vector3.MoveTowards(transform.position, target.position,
            (distance/duration) * Time.deltaTime);
    }
}

在协同程序中使用
Vector3.Lerp

Vector3 beginPos = new Vector3(10f, 10f, 0);
Vector3 endPos = new Vector3(20f, 10f, 0);
float time = 2;

void Start(){
    StartCoroutine(Move(beginPos, endPos, time));
}

IEnumerator Move(Vector3 beginPos, Vector3 endPos, float time){
    for(float t = 0; t < 1; t += Time.deltaTime / time){
        transform.position = Vector3.Lerp(beginPos, endPos, t);
        yield return null;
    }
}

除非你已经90岁了,否则就用tweeng吧

就这么简单

StartCoroutine(5f.Tweeng( (p)=>transform.position=p,
  startHere,
  endHere) );
它在5秒内从
startHere
endHere

就这些

tweeng扩展只有几行代码,例如:

你可以用tweeng、淡入音量、扭曲对象、设置类型大小的动画、淡入图像等等做任何事情


你将要从事的每一个大型项目,他们都已经使用tweeng。这再简单不过了。

这通常被称为Lerping(即线性插值)或Tweening(即介于两者之间)。你可以自己编写代码(如下面的各种答案所示),或使用资产商店上的几个软件包中的一个。我建议使用LeanTween或DOTween。一次可以接受的东西很多,但您确实需要tween。一旦您熟悉tween,使用tween只需要一行代码。(注意,不要像20年前那样使用“tween库”,只需tween)如何..使用FixeUpdate是完全错误的,当人们提到它时,这是一个非常糟糕的建议。你想简单而明显地设置每个视频帧的位置-即只是以正常方式使用更新或协同程序。FWIW它不是“每20毫秒”,这取决于设置的时间刻度。请注意,你(基本上)使用与物理相关的FixeUpdate,也就是说,在添加力时。当添加力时,确实是以物理引擎的速率进行的,即每个物理引擎帧。然后物理引擎显然会计算每个绘图帧的正确位置。请注意,绘图帧与物理帧完全无关,并且如果一个人没有使用物理(例如添加PhysX力),但实际上只是……设置位置,你必须(显然)对每个画框进行设置,即更新。(事实上,请注意,如果你不正确地使用FixedUpdate(即“PhysicsUpdate”)来移动东西!)如果Unity只是将FixedUpdate正确命名为PhysicsUpdate,那么Unity中就不会发生这种无休止的错误。谢谢你,伙计,从你的评论和下面更好的解决方案中学到了很多东西。
Lerp(a, b, t)   = (1-t)a + tb        
Lerp(a, b, 0)   = (1-0)a + 0b = a  
Lerp(a, b, 0.5) = (1-0.5)a + 0.5b = 0.5a + 0.5b     
Lerp(a, b, 1)   = (1-1)a + 1b = b        
StartCoroutine(5f.Tweeng( (p)=>transform.position=p,
  startHere,
  endHere) );