Unity3d Unity在一定的秒数内将对象移动到一个点(变换)
我想让物体在几秒钟内改变它的位置。例如,它将在5秒内“到达”一个点 选择一个位置并在固定的时间内到达它。有可能吗?它有功能吗 Lat示例。我的目标在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毫秒调用一次的特殊方法—无论渲染或性能如何—这样您就可以可
(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) );