Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions BopVisualEffects/Core/EntityCurveExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using UnityEngine;

namespace BopVisualEffects.Core;

/// <summary>
/// Extension helper for reading <see cref="AnimationCurve"/> values from <see cref="Entity"/> properties.
/// </summary>
internal static class EntityCurveExtensions
{
/// <summary>
/// Returns the <see cref="AnimationCurve"/> stored under <paramref name="key"/>, or
/// <paramref name="fallback"/> when the key is absent or its value is not an
/// <see cref="AnimationCurve"/>.
/// </summary>
internal static AnimationCurve GetAnimationCurve(this Entity entity, string key, AnimationCurve fallback)
{
if (entity.properties.TryGetValue(key, out var value) && value is AnimationCurve curve)
return curve;

return fallback;
}
}
17 changes: 13 additions & 4 deletions BopVisualEffects/Effects/CameraShake/CameraShakeEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
properties = new Dictionary<string, object>
{
["amplitude"] = 0.1f,
["frequency"] = 18.0f
["frequency"] = 18.0f,
["easing_curve"] = DefaultEasingCurve()
}
};
}
Expand All @@ -44,6 +45,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var durationBeats = Mathf.Max(0.01f, entity.length);
var amplitude = entity.GetFloat("amplitude");
var frequency = entity.GetFloat("frequency");
var easingCurve = entity.GetAnimationCurve("easing_curve", DefaultEasingCurve());
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -54,10 +56,15 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<CameraShakeRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, amplitude, frequency));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, amplitude, frequency, easingCurve));
}
}

private static AnimationCurve DefaultEasingCurve() => new AnimationCurve(
new Keyframe(0f, 1f, 0f, -1f),
new Keyframe(1f, 0f, -1f, 0f)
);

private sealed class CameraShakeRunner : MonoBehaviour
{
private bool _initialized;
Expand All @@ -69,18 +76,20 @@ private sealed class CameraShakeRunner : MonoBehaviour
private JukeboxScript? _jukebox;
private Transform? _targetTransform;
private Vector3 _initialLocalPosition;
private AnimationCurve _easingCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float amplitude, float frequency)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float amplitude, float frequency, AnimationCurve easingCurve)
{
_loader = loader;
_jukebox = jukebox;
_startBeat = startBeat;
_endBeat = endBeat;
_amplitude = Mathf.Max(0f, amplitude);
_frequency = Mathf.Max(0.1f, frequency);
_easingCurve = easingCurve;
InitializeTargetCamera();
}

Expand Down Expand Up @@ -116,7 +125,7 @@ private void LateUpdate()
}

var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
var envelope = 1f - progress;
var envelope = _easingCurve.Evaluate(progress);
if (envelope <= 0f)
{
Stop();
Expand Down
20 changes: 15 additions & 5 deletions BopVisualEffects/Effects/CameraTilt/CameraTiltEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
resizable = true,
properties = new Dictionary<string, object>
{
["angle"] = 5.0f
["angle"] = 5.0f,
["easing_curve"] = DefaultEasingCurve()
}
};
}
Expand All @@ -42,6 +43,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var log = ClassLogger.GetForClass<CameraTiltEffect>();
var durationBeats = Mathf.Max(0.01f, entity.length);
var angle = entity.GetFloat("angle");
var easingCurve = entity.GetAnimationCurve("easing_curve", DefaultEasingCurve());
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -52,10 +54,16 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<CameraTiltRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, angle));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, angle, easingCurve));
}
}

private static AnimationCurve DefaultEasingCurve() => new AnimationCurve(
new Keyframe(0f, 0f, 0f, Mathf.PI),
new Keyframe(0.5f, 1f, 0f, 0f),
new Keyframe(1f, 0f, -Mathf.PI, 0f)
);

private sealed class CameraTiltRunner : MonoBehaviour
{
private bool _initialized;
Expand All @@ -66,17 +74,19 @@ private sealed class CameraTiltRunner : MonoBehaviour
private JukeboxScript? _jukebox;
private Transform? _targetTransform;
private Quaternion _initialLocalRotation;
private AnimationCurve _easingCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float angle)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float angle, AnimationCurve easingCurve)
{
_loader = loader;
_jukebox = jukebox;
_startBeat = startBeat;
_endBeat = endBeat;
_angle = angle;
_easingCurve = easingCurve;
InitializeTargetCamera();
}

Expand Down Expand Up @@ -111,9 +121,9 @@ private void LateUpdate()
return;
}

// Swing tilt: rotate in one direction and back (full sine wave over the duration).
// Swing tilt: rotate in one direction and back (configurable curve over the duration).
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
var tiltAngle = _angle * Mathf.Sin(progress * Mathf.PI);
var tiltAngle = _angle * _easingCurve.Evaluate(progress);

_targetTransform!.localRotation = _initialLocalRotation * Quaternion.Euler(0f, 0f, tiltAngle);
}
Expand Down
25 changes: 15 additions & 10 deletions BopVisualEffects/Effects/ColorTint/ColorTintEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
["r"] = 1.0f,
["g"] = 0.0f,
["b"] = 0.0f,
["alpha"] = 0.25f
["alpha"] = 0.25f,
["easing_curve"] = DefaultEasingCurve()
}
};
}
Expand All @@ -49,6 +50,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var g = entity.GetFloat("g");
var b = entity.GetFloat("b");
var alpha = entity.GetFloat("alpha");
var easingCurve = entity.GetAnimationCurve("easing_curve", DefaultEasingCurve());
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -59,10 +61,17 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<ColorTintRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, r, g, b, alpha));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, r, g, b, alpha, easingCurve));
}
}

private static AnimationCurve DefaultEasingCurve() => new AnimationCurve(
new Keyframe(0f, 0f, 0f, 5f),
new Keyframe(0.2f, 1f, 5f, 0f),
new Keyframe(0.8f, 1f, 0f, -5f),
new Keyframe(1f, 0f, -5f, 0f)
);

private sealed class ColorTintRunner : MonoBehaviour
{
private bool _initialized;
Expand All @@ -75,11 +84,12 @@ private sealed class ColorTintRunner : MonoBehaviour
private MixtapeLoaderCustom? _loader;
private JukeboxScript? _jukebox;
private ColorTintOverlay? _overlay;
private AnimationCurve _easingCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float r, float g, float b, float alpha)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float r, float g, float b, float alpha, AnimationCurve easingCurve)
{
_loader = loader;
_jukebox = jukebox;
Expand All @@ -89,6 +99,7 @@ public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float
_g = Mathf.Clamp01(g);
_b = Mathf.Clamp01(b);
_maxAlpha = Mathf.Clamp01(alpha);
_easingCurve = easingCurve;
InitializeOverlay();
}

Expand Down Expand Up @@ -125,13 +136,7 @@ private void LateUpdate()

// Fade in over first 20%, hold, fade out over last 20%.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.2f)
envelope = Mathf.InverseLerp(0f, 0.2f, progress);
else if (progress > 0.8f)
envelope = 1f - Mathf.InverseLerp(0.8f, 1f, progress);
else
envelope = 1f;
var envelope = _easingCurve.Evaluate(progress);

if (_overlay != null)
_overlay.SetColor(_r, _g, _b, _maxAlpha * envelope);
Expand Down
25 changes: 15 additions & 10 deletions BopVisualEffects/Effects/Fog/FogEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
["g"] = 0.8f,
["b"] = 0.9f,
["alpha"] = 0.6f,
["height"] = 0.5f
["height"] = 0.5f,
["easing_curve"] = DefaultEasingCurve()
}
};
}
Expand All @@ -51,6 +52,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var b = entity.GetFloat("b");
var alpha = entity.GetFloat("alpha");
var height = entity.GetFloat("height");
var easingCurve = entity.GetAnimationCurve("easing_curve", DefaultEasingCurve());
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -61,10 +63,17 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<FogRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, r, g, b, alpha, height));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, r, g, b, alpha, height, easingCurve));
}
}

private static AnimationCurve DefaultEasingCurve() => new AnimationCurve(
new Keyframe(0f, 0f, 0f, 5f),
new Keyframe(0.2f, 1f, 5f, 0f),
new Keyframe(0.8f, 1f, 0f, -5f),
new Keyframe(1f, 0f, -5f, 0f)
);

private sealed class FogRunner : MonoBehaviour
{
private bool _initialized;
Expand All @@ -78,11 +87,12 @@ private sealed class FogRunner : MonoBehaviour
private MixtapeLoaderCustom? _loader;
private JukeboxScript? _jukebox;
private FogOverlay? _overlay;
private AnimationCurve _easingCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float r, float g, float b, float alpha, float height)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float r, float g, float b, float alpha, float height, AnimationCurve easingCurve)
{
_loader = loader;
_jukebox = jukebox;
Expand All @@ -93,6 +103,7 @@ public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float
_b = Mathf.Clamp01(b);
_maxAlpha = Mathf.Clamp01(alpha);
_height = Mathf.Clamp01(height);
_easingCurve = easingCurve;
InitializeOverlay();
}

Expand Down Expand Up @@ -129,13 +140,7 @@ private void LateUpdate()

// Fade in over first 20%, hold, fade out over last 20%.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.2f)
envelope = Mathf.InverseLerp(0f, 0.2f, progress);
else if (progress > 0.8f)
envelope = 1f - Mathf.InverseLerp(0.8f, 1f, progress);
else
envelope = 1f;
var envelope = _easingCurve.Evaluate(progress);

if (_overlay != null)
_overlay.SetParams(_r, _g, _b, _maxAlpha * envelope, _height);
Expand Down
25 changes: 15 additions & 10 deletions BopVisualEffects/Effects/Hsl/HslEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
["hue_shift"] = 0.0f,
["saturation"] = 1.0f,
["lightness"] = 0.0f,
["intensity"] = 1.0f
["intensity"] = 1.0f,
["easing_curve"] = DefaultEasingCurve()
}
};
}
Expand All @@ -51,6 +52,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var saturation = entity.GetFloat("saturation");
var lightness = entity.GetFloat("lightness");
var intensity = entity.GetFloat("intensity");
var easingCurve = entity.GetAnimationCurve("easing_curve", DefaultEasingCurve());
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -61,10 +63,17 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<HslRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, hueShift, saturation, lightness, intensity));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, hueShift, saturation, lightness, intensity, easingCurve));
}
}

private static AnimationCurve DefaultEasingCurve() => new AnimationCurve(
new Keyframe(0f, 0f, 0f, 5f),
new Keyframe(0.2f, 1f, 5f, 0f),
new Keyframe(0.8f, 1f, 0f, -5f),
new Keyframe(1f, 0f, -5f, 0f)
);

private sealed class HslRunner : MonoBehaviour
{
private bool _initialized;
Expand All @@ -78,12 +87,13 @@ private sealed class HslRunner : MonoBehaviour
private JukeboxScript? _jukebox;
private Camera? _camera;
private HslRequest? _request;
private AnimationCurve _easingCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat,
float hueShift, float saturation, float lightness, float intensity)
float hueShift, float saturation, float lightness, float intensity, AnimationCurve easingCurve)
{
_loader = loader;
_jukebox = jukebox;
Expand All @@ -93,6 +103,7 @@ public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float
_saturation = Mathf.Max(0f, saturation);
_lightness = Mathf.Clamp(lightness, -0.5f, 0.5f);
_maxIntensity = Mathf.Clamp01(intensity);
_easingCurve = easingCurve;
InitializeRequest();
}

Expand Down Expand Up @@ -129,13 +140,7 @@ private void LateUpdate()

// Fade in over first 20%, hold, fade out over last 20%.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.2f)
envelope = Mathf.InverseLerp(0f, 0.2f, progress);
else if (progress > 0.8f)
envelope = 1f - Mathf.InverseLerp(0.8f, 1f, progress);
else
envelope = 1f;
var envelope = _easingCurve.Evaluate(progress);

if (_request != null)
{
Expand Down
Loading