Animation fixes Demon

This commit is contained in:
Szymon Miś
2025-09-09 03:19:38 +02:00
parent 3b0b20a165
commit 9d6c237088
5 changed files with 633 additions and 254 deletions

View File

@@ -1,13 +1,14 @@
using Invector.vCharacterController.AI.FSMBehaviour;
using Lean.Pool;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
namespace DemonBoss.Magic
{
/// <summary>
/// Spawns exactly 3 crystal turrets around the opponent.
/// Now with per-spawn randomness: global rotation offset and per-turret angle/radius jitter.
/// Validates positions (ground/obstacles) and enforces minimum separation.
/// Now with per-spawn randomness and position validation.
/// </summary>
[CreateAssetMenu(menuName = "Invector/FSM/Actions/DemonBoss/Spawn 3 Turrets Radial")]
public class SA_SpawnTurretSmart : vStateAction
@@ -43,6 +44,13 @@ namespace DemonBoss.Magic
[Tooltip("Per-turret radius jitter (meters). 0 = disabled.")]
public float perTurretRadiusJitter = 0.75f;
[Header("One-off Overlay Clip (No Animator Params)")]
public AnimationClip overlayClip;
[Tooltip("Playback speed (1 = normal)")] public float overlaySpeed = 1f;
[Tooltip("Blend-in seconds (instant in this minimal impl)")] public float overlayFadeIn = 0.10f;
[Tooltip("Blend-out seconds (instant in this minimal impl)")] public float overlayFadeOut = 0.10f;
[Header("Debug")]
public bool enableDebug = false;
@@ -52,11 +60,25 @@ namespace DemonBoss.Magic
private Transform npcTransform;
private Transform playerTransform;
private readonly System.Collections.Generic.List<Vector3> _lastPlanned = new System.Collections.Generic.List<Vector3>(3);
private readonly System.Collections.Generic.List<Vector3> _lastPlanned =
new System.Collections.Generic.List<Vector3>(3);
// --- Playables runtime ---
private PlayableGraph _overlayGraph;
private AnimationPlayableOutput _overlayOutput;
private AnimationClipPlayable _overlayPlayable;
private bool _overlayPlaying;
private float _overlayStopAtTime;
public override void DoAction(vIFSMBehaviourController fsmBehaviour, vFSMComponentExecutionType executionType = vFSMComponentExecutionType.OnStateUpdate)
{
if (executionType == vFSMComponentExecutionType.OnStateEnter) OnStateEnter(fsmBehaviour);
else if (executionType == vFSMComponentExecutionType.OnStateUpdate)
{
// Auto-stop overlay when finished
if (_overlayPlaying && Time.time >= _overlayStopAtTime) StopOverlayWithFade();
}
else if (executionType == vFSMComponentExecutionType.OnStateExit) OnStateExit(fsmBehaviour);
}
@@ -70,6 +92,8 @@ namespace DemonBoss.Magic
if (npcAnimator != null && !string.IsNullOrEmpty(animatorBlockingBool))
npcAnimator.SetBool(animatorBlockingBool, true);
PlayOverlayOnce(npcTransform);
SpawnThreeTurretsRadial(fsmBehaviour);
DEC_CheckCooldown.SetCooldownStatic(fsmBehaviour, "Turret", 12f);
@@ -79,6 +103,8 @@ namespace DemonBoss.Magic
{
if (npcAnimator != null && !string.IsNullOrEmpty(animatorBlockingBool))
npcAnimator.SetBool(animatorBlockingBool, false);
StopOverlayWithFade();
}
private void FindPlayer(vIFSMBehaviourController fsmBehaviour)
@@ -270,5 +296,54 @@ namespace DemonBoss.Magic
prevPoint = newPoint;
}
}
private void PlayOverlayOnce(Transform owner)
{
if (overlayClip == null) return;
if (npcAnimator == null)
npcAnimator = owner.GetComponent<Animator>();
if (npcAnimator == null) return;
StopOverlayImmediate(); // safety
_overlayGraph = PlayableGraph.Create("ActionOverlay(SpawnTurret)");
_overlayGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
_overlayPlayable = AnimationClipPlayable.Create(_overlayGraph, overlayClip);
_overlayPlayable.SetApplyFootIK(false);
_overlayPlayable.SetApplyPlayableIK(false);
_overlayPlayable.SetSpeed(Mathf.Max(0.0001f, overlaySpeed));
_overlayOutput = AnimationPlayableOutput.Create(_overlayGraph, "AnimOut", npcAnimator);
_overlayOutput.SetSourcePlayable(_overlayPlayable);
_overlayOutput.SetWeight(1f);
_overlayGraph.Play();
_overlayPlaying = true;
float len = overlayClip.length / Mathf.Max(0.0001f, overlaySpeed);
_overlayStopAtTime = Time.time + len;
if (enableDebug) Debug.Log("[SA_SpawnTurretSmart] Overlay clip started via Playables");
}
private void StopOverlayImmediate()
{
if (_overlayGraph.IsValid())
{
_overlayGraph.Stop();
_overlayGraph.Destroy();
}
_overlayPlaying = false;
}
private void StopOverlayWithFade()
{
if (!_overlayPlaying) { StopOverlayImmediate(); return; }
if (_overlayOutput.IsOutputNull() == false) _overlayOutput.SetWeight(0f);
StopOverlayImmediate();
if (enableDebug) Debug.Log("[SA_SpawnTurretSmart] Overlay clip stopped");
}
}
}