Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将对象移动到鼠标单击时存储的目标?_C#_Loops_Unity3d_Coroutine - Fatal编程技术网

C# 如何将对象移动到鼠标单击时存储的目标?

C# 如何将对象移动到鼠标单击时存储的目标?,c#,loops,unity3d,coroutine,C#,Loops,Unity3d,Coroutine,我正在努力实现最简单的事情。我有平滑移动一个对象的代码,我希望它停在一个特定的距离上,这个距离与点击按钮时对象所在的位置有关。所以我不能在任何更新每帧的函数中存储位置。当前,对象只是开始移动,并没有停止 void Update() { Vector3 targetPosition = new Vector3(transform.position.x - 1, transform.position.y, transform.position.z); if

我正在努力实现最简单的事情。我有平滑移动一个对象的代码,我希望它停在一个特定的距离上,这个距离与点击按钮时对象所在的位置有关。所以我不能在任何更新每帧的函数中存储位置。当前,对象只是开始移动,并没有停止

void Update()
    {
        Vector3 targetPosition = new Vector3(transform.position.x - 1, transform.position.y, transform.position.z);

        if (movement == true)
        {
            float step = speed * Time.deltaTime;
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
        }
    }

    public void coroutineStarter()
    {
        float targetPosition = transform.position.x - 1;
        StartCoroutine(OnClick(targetPosition));
    }



    IEnumerator OnClick(float targetPosition)
    {
        if (transform.position.x != targetPosition)
        {
            movement = true;
        }
        else
        {
            movement = false;
            yield return null;
        }
    }
}

我应该指定按下按钮启动
coroutineStarter
。我尝试在
OnClick
中使用while循环而不是if语句,但显然,在任何地方使用while循环都会冻结无限的统一性,如果不是无限的统一性,则会在循环期间冻结统一性。

我不会将协同程序与
Update
中运行的代码混淆。协同程序已经像一个临时的
Update
方法,因此您可以简单地执行

public void coroutineStarter()
{
    var targetPosition = transform.position + Vector3.left;
    StartCoroutine(OnClick(targetPosition));
}

IEnumerator OnClick(Vector3 targetPosition)
{
    while (transform.position.x != targetPosition)
    {
        float step = speed * Time.deltaTime;
        transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);

        // Important! Tells Unity to pause here, render this frame
        // and continue from here in the next frame
        yield return null;
    }

    // When done set the position fixed once
    // since == has a precision of 0.00001 so it never reaches an exact position
    transform.position = targetPosition;
}
这将以恒定速度将对象移动到目标位置


稍微不同的方法是在特定时间内移动对象,但允许使用
Vector3.Lerp
SmoothStep

IEnumerator OnClick(Vector3 targetPosition)
{
    var startPosition = transform.position;
    var distance = Vector3.Distance(startPosition, targetPosition);

    if(distance <= 0) yield break;

    var duration = distance / speed;
    var timePassed = 0f;

    while (timePassed < duration)
    {
        var factor = timePassed / duration;
        // Optionally add easing
        factor = Mathf.SmoothStep(0,1,factor);

        transform.position = Vector3.Lerp(startPosition, targetPosition, factor);

        // increase by time since last frame avoiding overshooting
        timePassed += Mathf.Min(Time.deltaTime, duration - timePassed);

        // Important! Tells Unity to pause here, render this frame
        // and continue from here in the next frame
        yield return null;
    }

    // When done set the position fixed once
    // this time just in case you never know ;)
    transform.position = targetPosition;
}
IEnumerator OnClick(Vector3 targetPosition)
{
var startPosition=transform.position;
var距离=矢量3.距离(起始位置、目标位置);

if(distance)如果
在其中返回null;
则不会冻结Unity。这会告诉Unity暂停例程,渲染帧并在下一帧中继续。