Reputation: 735
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
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
Upvotes: 1