KevinM1990112qwq
KevinM1990112qwq

Reputation: 735

Run lerp over timer

First off, I am not using any kind of game engine, I am modding a game in C# and I am NOT using UnityEngine API so I do not have any Update() functions.

So I am trying to figure out how I could create a timer, some standard out of the box C# timer that would increase the lerp distance over a set speed.

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

I would like to wrap this in a timer that every 100ms it will increase the float at the end of the lerp by some set amount over the duration of a time, so say I set float speed = 5f; I want to increase that lerp distance every 100ms for 5 seconds until it reaches its goal.

Is this possible to do?

Upvotes: 1

Views: 523

Answers (1)

ProgrammingLlama
ProgrammingLlama

Reputation: 38767

I've created an example timer class which will slowly increment a value by a given amount until it reaches 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();
    }
}

Sample usage:

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();

So you would call this once, and then it would keep going until it reaches 100% (endRotation).

It's not necessarily the code you should use, but it should illustrate how you can use a timer to increase the value over time.


Edit to add some clarity to what a lerp function does:

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

Imagine we call this every 10% from 4 to 125. We would get the following results:

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

Upvotes: 1

Related Questions