2021-09-09 20:42:29 -04:00

79 lines
2.7 KiB
Markdown

# Variable Rate
Menu Path : **Spawn > Variable Rate**
The Variable Rate Block uses a more advanced approach than the [Constant Rate Block](Block-ConstantRate.md). The spawn rate this Block applies is linearly interpolated between two rates within an interval defined by the period.
## Block compatibility
This Block is compatible with the following Contexts:
- [Spawn](Context-Spawn.md)
## Block properties
| **Input** | **Type** | **Description** |
| ---------- | -------- | ------------------------------------------------------------ |
| **Rate** | Vector2 | The two values this Block uses to calculate the spawn rate. The current rate is always a value between the two dimensions of this Vector2. |
| **Period** | Vector2 | The minimum and maximum time period before this Block calculates a new spawn rate. A higher period leads to a smoother change in rate while a small period leads to a higher frequency rate change. |
## Remarks
You can emulate this Block with the following equivalent custom spawner callback implementation:
```C#
class VariableRateEquivalent : VFXSpawnerCallbacks
{
public class InputProperties
{
public Vector2 Rate;
public Vector2 Period;
}
static private readonly int rateID = Shader.PropertyToID("Rate");
static private readonly int periodID = Shader.PropertyToID("Period");
public sealed override void OnPlay(VFXSpawnerState state, VFXExpressionValues vfxValues, VisualEffect vfxComponent)
{
}
float m_PrevRate;
float m_NextRate;
float m_PrevTime;
float m_NextTime;
void AdvanceRate(float totalTime, Vector2 rate, Vector2 period)
{
m_PrevRate = m_NextRate;
m_PrevTime = totalTime;
m_NextRate = Random.Range(rate.x, rate.y);
m_NextTime = totalTime + Random.Range(period.x, period.y);
}
public sealed override void OnUpdate(VFXSpawnerState state, VFXExpressionValues vfxValues, VisualEffect vfxComponent)
{
if (state.newLoop)
AdvanceRate(state.totalTime, vfxValues.GetVector2(rateID), vfxValues.GetVector2(periodID));
if (state.playing)
{
float range = m_NextTime - m_PrevTime;
float ratio = 1.0f;
if (range > 0.0f)
ratio = Mathf.Clamp01((state.totalTime - m_PrevTime) / range);
float rate = Mathf.Lerp(m_PrevRate, m_NextRate, ratio);
if (ratio == 1.0f)
AdvanceRate(state.totalTime, vfxValues.GetVector2(rateID), vfxValues.GetVector2(periodID));
state.spawnCount += rate * state.deltaTime;
}
}
public sealed override void OnStop(VFXSpawnerState state, VFXExpressionValues vfxValues, VisualEffect vfxComponent)
{
}
}
```