在计时器上运行lerp

时间:2018-10-04 06:51:45

标签: c# .net lerp

首先,我没有使用任何类型的游戏引擎,我正在使用C#修改游戏,并且没有使用UnityEngine API,所以我没有任何Update()函数。

所以我试图弄清楚如何创建计时器,一些标准的现成C#计时器,它将在设定速度上增加lerp距离。

model.rotationM = Vector3.Lerp(model.rotation, model.rotationM, (float)0.016);
NAPI.Entity.SetEntityRotation(model.handle, model.rotationM);

我想将其包装在一个计时器中,使其每100毫秒将在一段持续时间内将lerp末尾的浮点数增加一些设置量,所以说我设置了float speed = 5f; 我想每5秒钟增加一次束缚距离,持续5秒钟,直到达到目标为止。

这可能吗?

1 个答案:

答案 0 :(得分:1)

我创建了一个示例计时器类,该类将以一个给定的量缓慢增加一个值,直到达到100%(1.0):

public class LerpTimer : IDisposable
{
    private readonly Timer _timer;
    private readonly float _incrementPercentage = 0;
    public event EventHandler<float> DoLerp;
    public event EventHandler Complete;
    private bool _isDisposed = false;
    private float _current;

    public LerpTimer(double frequencyMs, float incrementPercentage)
    {
        if (frequencyMs <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(frequencyMs), "Frequency must be greater than 1ms.");
        }

        if (incrementPercentage < 0 || incrementPercentage > 1)
        {
            throw new ArgumentOutOfRangeException(nameof(incrementPercentage), "Increment percentage must be a value between 0 and 1");
        }
        _timer = new Timer(frequencyMs);
        _timer.Elapsed += _timer_Elapsed;
        _incrementPercentage = incrementPercentage;
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (_isDisposed)
        {
            return;
        }

        if (this.Current < 1)
        {
            this.Current = Math.Min(1, this.Current + _incrementPercentage);
            this.DoLerp?.Invoke(this, this.Current);
        }

        if (this.Current >= 1)
        {
            this._timer.Stop();
            this.Complete?.Invoke(this, EventArgs.Empty);
        }
    }

    public float Current
    {
        get
        { 
            if (_isDisposed)
            {
                throw new ObjectDisposedException(nameof(LerpTimer));
            }
            return _current;
        }
        set => _current = value;
    }

    public void Start()
    {
        if (_isDisposed)
        {
            throw new ObjectDisposedException(nameof(LerpTimer));
        }

        if (_timer.Enabled)
        {
            throw new InvalidOperationException("Timer already running.");
        }
        this.Current = 0;
        _timer.Start();
    }

    public void Stop()
    {
        if (_isDisposed)
        {
            throw new ObjectDisposedException(nameof(LerpTimer));
        }

        if (!_timer.Enabled)
        {
            throw new InvalidOperationException("Timer not running.");
        }
        _timer.Stop();
    }

    public void Dispose()
    {
        _isDisposed = true;
        _timer?.Dispose();
    }
}

样品用量:

var lerpTimer = new LerpTimer(100, 0.016f);
lerpTimer.DoLerp += (sender, value) => {
    model.rotationM = Vector3.Lerp(startRotation, endRotation, value);
    NAPI.Entity.SetEntityRotation(model.handle, model.rotationM);
};
lerpTimer.Start();

因此您将调用一次,然后它将继续进行直到达到100%(endRotation)。

不一定要使用代码,但应说明如何使用计时器随时间增加值。


编辑以使lerp函数的功能更清晰:

double lerp(double start, double end, double percentage)
{
    return start + ((end - start) * percentage);
}

想象一下,我们将每10%的比例称为4到125。我们将得到以下结果:

0%    4
10%   16.1
20%   28.2
30%   40.3
40%   52.4
50%   64.5
60%   76.6
70%   88.7
80%   100.8
90%   112.9
100%  125

Try it online