mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 10:35:34 +00:00
Animated switches
This commit is contained in:
parent
07be138a1b
commit
f7240e1167
6 changed files with 422 additions and 233 deletions
|
|
@ -15,13 +15,13 @@ public partial class Switch3D : Interactable3D
|
|||
[Export] public ActivationType ActivationType { get; set; } = ActivationType.Toggle;
|
||||
|
||||
[Signal]
|
||||
public delegate void OnActivatedEventHandler(ActivationType activationType);
|
||||
public delegate void OnActivatedEventHandler(ActivationType activationType, bool success);
|
||||
|
||||
private AudioStreamPlayer _activationSound;
|
||||
private AudioStreamPlayer _denySound;
|
||||
|
||||
private readonly string _activationSoundName = "ActivationSound";
|
||||
private readonly string _denySoundName = "ActivationSound";
|
||||
private readonly string _denySoundName = "DenySound";
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
|
|
@ -60,8 +60,6 @@ public partial class Switch3D : Interactable3D
|
|||
_denySound?.Play();
|
||||
return false;
|
||||
}
|
||||
|
||||
EmitSignal(SignalName.OnActivated, (int)activationTypeToUse);
|
||||
|
||||
// Compatibility for old single system
|
||||
bool success = ActivateTarget(Target, activationTypeToUse);
|
||||
|
|
@ -83,13 +81,14 @@ public partial class Switch3D : Interactable3D
|
|||
_denySound?.Play();
|
||||
}
|
||||
|
||||
EmitSignal(SignalName.OnActivated, (int)activationTypeToUse, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool ActivateTarget(Node target, ActivationType activationType = ActivationType.Toggle)
|
||||
{
|
||||
if (target is not IActivable activable) return false;
|
||||
activable?.Activate(activationType);
|
||||
activable.Activate(activationType);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
159
Scripts/Interactables/SwitchAnimationManager.cs
Normal file
159
Scripts/Interactables/SwitchAnimationManager.cs
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Interactables;
|
||||
|
||||
/// <summary>
|
||||
/// Listens to the <see cref="Switch3D.OnActivated"/> signal and plays a named animation
|
||||
/// on an <see cref="AnimationPlayer"/> that reflects the switch's new state.
|
||||
///
|
||||
/// Works with any Switch3D subclass (including <see cref="ShootableSwitch3D"/>).
|
||||
///
|
||||
/// Usage:
|
||||
/// 1. Add this node as a child of the Switch3D node.
|
||||
/// 2. Optionally assign <see cref="TargetSwitch"/> and <see cref="TargetAnimationPlayer"/>
|
||||
/// in the inspector; if left empty both are discovered automatically from the parent.
|
||||
/// 3. Set the three animation name exports to match animations in your AnimationPlayer.
|
||||
/// Leave a name empty to skip playing an animation for that state.
|
||||
/// </summary>
|
||||
[Tool]
|
||||
public partial class SwitchAnimationManager : Node
|
||||
{
|
||||
/// <summary>
|
||||
/// The switch to listen to. Auto-discovered from the parent if left empty.
|
||||
/// </summary>
|
||||
[Export] public Switch3D TargetSwitch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AnimationPlayer to drive. Auto-discovered from the parent if left empty.
|
||||
/// </summary>
|
||||
[Export] public AnimationPlayer TargetAnimationPlayer { get; set; }
|
||||
|
||||
// --- State-based animation name exports ---
|
||||
|
||||
/// <summary>Animation to play when the switch transitions to the enabled (on) state.</summary>
|
||||
[Export] public StringName AnimationEnabled { get; set; } = "";
|
||||
|
||||
/// <summary>Animation to play when the switch transitions to the disabled (off) state.</summary>
|
||||
[Export] public StringName AnimationDisabled { get; set; } = "";
|
||||
|
||||
/// <summary>Animation to play when the switch is destroyed.</summary>
|
||||
[Export] public StringName AnimationDestroyed { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Whether the switch is currently considered enabled (on) or disabled (off).
|
||||
/// Updated on each successful activation.
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// When true the switch has been destroyed and will no longer respond to activations.
|
||||
/// </summary>
|
||||
public bool IsDestroyed { get; private set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (Engine.IsEditorHint()) return;
|
||||
|
||||
ResolveReferences();
|
||||
|
||||
if (TargetSwitch is null)
|
||||
{
|
||||
GD.PushWarning($"[SwitchAnimationManager:{Name}] No Switch3D found. Assign TargetSwitch or place this node as a child of one.");
|
||||
return;
|
||||
}
|
||||
|
||||
TargetSwitch.OnActivated += OnSwitchActivated;
|
||||
|
||||
// Start in the disabled state so the AnimationPlayer is running from the beginning.
|
||||
PlayAnimation(AnimationDisabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills in <see cref="TargetSwitch"/> and <see cref="TargetAnimationPlayer"/> from the
|
||||
/// parent node when they have not been assigned explicitly in the inspector.
|
||||
/// </summary>
|
||||
private void ResolveReferences()
|
||||
{
|
||||
var parent = GetParent();
|
||||
|
||||
if (TargetSwitch is null)
|
||||
TargetSwitch = parent as Switch3D;
|
||||
|
||||
if (TargetAnimationPlayer is null)
|
||||
TargetAnimationPlayer = parent?.FindChild("AnimationPlayer", recursive: true, owned: false) as AnimationPlayer
|
||||
?? parent?.GetNodeOrNull<AnimationPlayer>("AnimationPlayer");
|
||||
}
|
||||
|
||||
private void OnSwitchActivated(ActivationType activationType, bool success)
|
||||
{
|
||||
// Ignore failed activations and permanently destroyed switches.
|
||||
if (!success || IsDestroyed) return;
|
||||
|
||||
UpdateState(activationType);
|
||||
|
||||
StringName animationName = IsDestroyed ? AnimationDestroyed
|
||||
: IsEnabled ? AnimationEnabled
|
||||
: AnimationDisabled;
|
||||
|
||||
PlayAnimation(animationName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transitions <see cref="IsEnabled"/> (and <see cref="IsDestroyed"/>) according to
|
||||
/// the activation type that was successfully applied:
|
||||
/// <list type="bullet">
|
||||
/// <item><see cref="ActivationType.Enable"/> / <see cref="ActivationType.Open"/> → enabled</item>
|
||||
/// <item><see cref="ActivationType.Disable"/> / <see cref="ActivationType.Close"/> → disabled</item>
|
||||
/// <item><see cref="ActivationType.Toggle"/> / <see cref="ActivationType.Use"/> → inverted</item>
|
||||
/// <item><see cref="ActivationType.Destroy"/> → disabled + destroyed</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
private void UpdateState(ActivationType activationType)
|
||||
{
|
||||
switch (activationType)
|
||||
{
|
||||
case ActivationType.Enable:
|
||||
case ActivationType.Open:
|
||||
IsEnabled = true;
|
||||
break;
|
||||
|
||||
case ActivationType.Disable:
|
||||
case ActivationType.Close:
|
||||
IsEnabled = false;
|
||||
break;
|
||||
|
||||
case ActivationType.Toggle:
|
||||
case ActivationType.Use:
|
||||
IsEnabled = !IsEnabled;
|
||||
break;
|
||||
|
||||
case ActivationType.Destroy:
|
||||
IsEnabled = false;
|
||||
IsDestroyed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plays the given animation on <see cref="TargetAnimationPlayer"/> if the name is non-empty
|
||||
/// and the animation exists. Pushes a warning otherwise.
|
||||
/// </summary>
|
||||
private void PlayAnimation(StringName animationName)
|
||||
{
|
||||
if (animationName is null || animationName == "") return;
|
||||
|
||||
if (TargetAnimationPlayer is null)
|
||||
{
|
||||
GD.PushWarning($"[SwitchAnimationManager:{Name}] No AnimationPlayer found. Assign TargetAnimationPlayer or add one under the switch.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TargetAnimationPlayer.HasAnimation(animationName))
|
||||
{
|
||||
GD.PushWarning($"[SwitchAnimationManager:{Name}] AnimationPlayer has no animation named '{(string)animationName}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
TargetAnimationPlayer.Play(animationName);
|
||||
}
|
||||
}
|
||||
1
Scripts/Interactables/SwitchAnimationManager.cs.uid
Normal file
1
Scripts/Interactables/SwitchAnimationManager.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cklsqt246d571
|
||||
Loading…
Add table
Add a link
Reference in a new issue