运行 超越计时器
Run lerp over timer
首先,我没有使用任何类型的游戏引擎,我正在用 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;
我想每 100 毫秒增加一次 lerp 距离,持续 5 秒,直到达到目标。
这可以吗?
我创建了一个示例计时器 class,它将按给定的量缓慢增加一个值,直到它达到 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);
}
假设我们从 4 到 125 每 10% 调用一次。我们将得到以下结果:
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
首先,我没有使用任何类型的游戏引擎,我正在用 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;
我想每 100 毫秒增加一次 lerp 距离,持续 5 秒,直到达到目标。
这可以吗?
我创建了一个示例计时器 class,它将按给定的量缓慢增加一个值,直到它达到 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);
}
假设我们从 4 到 125 每 10% 调用一次。我们将得到以下结果:
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