使对象向一个方向滑动

时间:2018-11-18 12:01:51

标签: c# unity3d

我想使Rigidbody对象向右或向左滑动。

例如,如果他的位置为0 X,则他将向一个方向滑动1,然后沿该方向停止并停止。

通过施加力,对象将继续沿该方向移动,我希望对象移动,然后停止。

修改 这就是我尝试过的

void Update() {

    if (Input.GetKeyDown("d") && !isMoving) {
        StartCoroutine(MoveToPos(Vector3.right));
    }

    if (Input.GetKeyDown("a") && !isMoving) {
        StartCoroutine(MoveToPos(Vector3.left));
    }
}

public IEnumerator MoveToPos(Vector3 direction) {
    isMoving = true;
    var t = 0f;
    var startPosition = transform.position;
    var value = direction == Vector3.right? 1 : -1;
    while (t < 1f) {
        t += 0.05f;
        var endPosition = transform.position;
        endPosition.x = startPosition.x + value * t;
        transform.position = Vector3.Lerp(transform.position, endPosition, t);
        Debug.Log(player.position);
        yield return null;
    }
    isMoving = false;
}

但是可悲的是,它的动画非常丑陋,对象在一段时间后会捕捉到最终位置,看起来不像对象滑动然后停在那里。就像没有加减速一样。

编辑2

我尝试调整值并进行减速运动。 Kinda工作正常,但我认为它仍需要改进。

public IEnumerator MoveToPos(Vector3 direction) {
    isMoving = true;
    var t = 0.0;
    var startPosition = transform.position;
    var value = direction == Vector3.right ? 1 : -1;
    while (t < 1) {
        if (t < 0.5) t += 0.1;
        else t += 0.03125;
        Debug.Log(t);
        var endPosition = transform.position;
        endPosition.x = startPosition.x + value * (float)t;
        transform.position = Vector3.Lerp(transform.position, endPosition, (float)t);
        yield return null;
    }
    isMoving = false;
}

我猜想调整加速度和减速度的值会使动画更平滑。

2 个答案:

答案 0 :(得分:0)

简单的方法是这样的:

void Update()
    {
        if(Input.GetKeyDown(KeyCode.A))
            transform.Translate(Vector3.right * 1);
    }

成为“键”的条件是移动对象,并更改Vector3.right的对应方向(左,上,下...)

但是我建议使用Lerp函数使它更加逼真: https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

答案 1 :(得分:-1)

您的代码中几乎没有错误:

1 。不要用固定的数字增加时间(t变量)。为此使用Time.deltaTime

2 。请勿使用带有transform的Rigidbody来移动GameObject。因此,请勿执行transform.position = xxxtransform.Translate(xxx)。移动刚体对象时,请使用Rigidbody.MovePosition函数。

3 使用isKinematic函数移动刚体时,应在刚体上启用Rigidbody.MovePosition,因为它非常平滑。

最后,要使其在运动完成后立即停止,请将velocityangularVelocity设置为零。

您已修复的新功能:

bool isMoving = false;
IEnumerator MoveToPos(Rigidbody targetObject, Vector3 direction, float duration, float units = 1f)
{
    isMoving = true;
    targetObject.isKinematic = true;

    float counter = 0;

    //Get the current position of the object to be moved
    Vector3 startPos = targetObject.position;
    //Get destination position
    Vector3 toPosition = startPos + direction * units;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        //targetObject.position = Vector3.Lerp(startPos, toPosition, counter / duration);
        Vector3 newPos = Vector3.Lerp(startPos, toPosition, counter / duration); ;
        targetObject.MovePosition(newPos);
        yield return null;
    }

    targetObject.isKinematic = false;
    //Stop right away
    targetObject.velocity = Vector3.zero;
    targetObject.angularVelocity = Vector3.zero;
    isMoving = false;
}

用法:

Rigidbody rb = GetComponent<Rigidbody>();
StartCoroutine(MoveToPos(rb, Vector3.right, 3f, 1f));