如何在快速按下F时多次将对象向下/向上平滑而无需等待?

时间:2017-12-24 07:48:04

标签: c# unity3d unity5

第一个脚本用于按F并调用ScaleChange:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DroidMove : MonoBehaviour
{
    public GameObject droid;
    public ChangeScale changeScale;

    private bool toDisplay = false;

    private void Start()
    {
        droid.transform.localScale = new Vector3(0, 0, 0); 
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.F))
        {
            toDisplay = !toDisplay;
            changeScale.Scale(toDisplay);
        }
    }
}

第二个脚本进行缩放:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChangeScale : MonoBehaviour
{
    public GameObject objectToScale;

    private float _currentScale = InitScale;
    private const float TargetScale = 0.7f;
    private const float InitScale = 0f;
    private const int FramesCount = 10;
    private const float AnimationTimeSeconds = 0.1f;
    private float _deltaTime = AnimationTimeSeconds / FramesCount;
    private float _dx = (TargetScale - InitScale) / FramesCount;

    private IEnumerator ScaleUp()
    {
        bool upscaling = true;
        while (upscaling)
        {
            _currentScale += _dx;
            if (_currentScale > TargetScale)
            {
                upscaling = false;
                _currentScale = TargetScale;
            }
            objectToScale.transform.localScale = Vector3.one * _currentScale;
            yield return new WaitForSeconds(_deltaTime);
        }
    }

    private IEnumerator ScaleDown()
    {
        bool downscaling = true;
        while (downscaling)
        {
            _currentScale -= _dx;
            if (_currentScale < InitScale)
            {
                downscaling = false;
                _currentScale = InitScale;
            }
            objectToScale.transform.localScale = Vector3.one * _currentScale;
            yield return new WaitForSeconds(_deltaTime);
        }
    }

    public void Scale(bool scaleUp)
    {
        if (scaleUp)
        {
            StartCoroutine(ScaleUp());
        }
        else
        {
            StartCoroutine(ScaleDown());
        }
    }
}

问题是,如果我按下F并且它开始放大并且还没有完成缩放,我再次按F而不是开始缩小它就像暂停一样,如果我继续按F,它将继续放大每个时间有点。

但我想要做的是当我第一次按下F开始放大时,如果在中间同时缩放我再次按F然后从当前缩放点开始缩小,如果我再次按F然后上下都像一个平滑的开关。

但现在每次按F多次都会暂停。

就像我现在需要等待缩放才能先完成然后我再次按下F,如果不是它只会暂停它我希望每次按F它会切换放大/缩小

1 个答案:

答案 0 :(得分:2)

向上和向下放大不需要多个功能。一个人应该这样做。只需将比例量作为参数然后重新使用该功能即可。比例MinMax应该是Vector3而不是float,因为这是表示比例的方式,并且您想要覆盖所有三个轴(x,y,z)。

如何解决按下按键需要花费很长时间才能完成扩展而不切换方向的问题:

启动协程时,获取对该正在运行的协程的引用。在再次启动协程之前,请使用旧引用来停止旧引用。就这么简单。重写整个代码比修复现有代码要好得多。

以下是您的代码的简化版本。请务必从编辑器中设置minSizemaxSizeobjectToScale变量。如果您有任何疑问,请参阅代码注释。

public GameObject objectToScale;
public Vector3 minSize;
public Vector3 maxSize;

private bool scaleUp = false;
private Coroutine scaleCoroutine;

// Use this for initialization
void Update()
{
    if (Input.GetKeyDown(KeyCode.F))
    {
        //Flip the scale direction when F key is pressed
        scaleUp = !scaleUp;

        //Stop old coroutine
        if (scaleCoroutine != null)
            StopCoroutine(scaleCoroutine);

        //Scale  up
        if (scaleUp)
        {
            //Start new coroutine and scale up within 5 seconds and return the coroutine reference
            scaleCoroutine = StartCoroutine(scaleOverTime(objectToScale, maxSize, 5f));
        }

        //Scale Down
        else
        {
            //Start new coroutine and scale down within 5 seconds and return the coroutine reference
            scaleCoroutine = StartCoroutine(scaleOverTime(objectToScale, minSize, 5f));
        }
    }
}

IEnumerator scaleOverTime(GameObject targetObj, Vector3 toScale, float duration)
{
    float counter = 0;

    //Get the current scale of the object to be scaled
    Vector3 startScaleSize = targetObj.transform.localScale;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        targetObj.transform.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);
        yield return null;
    }
}