如何以任意所需的速度将角色从一个点移动到特定点?

问题描述

我从这段代码中使用过,但没有做到这一点:

public Transform[] points;
public float speed;

private void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "door1") 
    {       
        transform.position = Vector3.Lerp(transform.position,points[1].position,speed * Time.deltaTime);
    }
}

就是说,我希望猪在撞到扳机时以期望的速度到达地面上的更高点(请参阅所附照片以查看它)

How can I move a character from one point to a specific point at any desired speed?

解决方法

这里有两个问题:

  • 当您进入对撞机时,您恰好一次呼叫了该行,因此该移动适用于单帧
  • Lerp使用01之间的因数在两个位置之间线性插值。您每次都以当前位置为起点,因此,如果连续调用该位置,将会发生的情况,这近似于该位置越来越慢,而这并不是您所描述的。您想以恒定的速度移动。

您最可能会为此使用CoroutineMoveTowards

private void OnTriggerEnter2D(Collider2D other)
{
    // Better use CompareTag here
    if (other.CompareTag("door1"))
    {     
        // Start a routine for the continuous movement
        StartCoroutine(MoveTo(points[1].position,speed);
    }
}

private IEnumerator MoveTo(Vector3 targetPosition,float linearSpeed)
{
    // This uses an approximation of 0.00001 for equality
    while(transform.position != targetPosition)
    {
        // with a constant speed of linearSpeed Units / second
        // move towards the target position without overshooting
        transform.position = Vector3.MoveTowards(transform.position,targetPosition,linearSpeed * Time.deltaTime);

        // Tell Unity to "pause" the routine here,render this frame
        // and continue from here in the next frame
        yield return null;
    }

    // to be sure to end up with exact values set the target position fix when done
    transform.position = targetPosition;
}

或者看起来更复杂,但是功能更强大,它是根据速度来计算所需的时间,但是仍然添加一些平滑处理,例如

private void OnTriggerEnter2D(Collider2D other)
{
    if (other.CompareTag("door1"))
    {     
        StartCoroutine (MoveTo(points[1].position,float averageSpeed)
{ 
    // store the initial position
    var from = transform.position;
    // Get the expected duration depending on distance and speed
    var duration = Vector3.Distance(from,targetPosition) / averageSpeed;

    // This is increased over time
    var timePassed = 0;
    while(timePassed < duration)
    {
        // This linear grows from 0 to 1
        var factor = timePassed / duration;
        // Adds some ease-in and ease-out at beginning and end of the movement
        factor = Mathf.SmoothStep(0,1,factor);

        // linear interpolate on the smoothed factor 
        transform.position = Vector3.Lerp(from,factor);

        // increase by time passed since last frame
        timePassed += Time.deltaTime;

        // Tell Unity to "pause" the routine here,render this frame
        // and continue from here in the next frame
        yield return null;
    }

    // to be sure to end up with exact values set the target position fix when done
    transform.position = targetPosition;
}
,

OnTriggerEnter2D在每次对撞机输入中仅被调用一次。假设您只将其移动speed * Time.deltaTime,而Time.deltaTime的范围为0.008-0.100,则它可能只会稍微移动。

根据您想要的内容,确定要完全移动对象还是设置一个标记以在update()方法中开始移动它?

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...