Animation fixes Demon
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
using Invector.vCharacterController.AI.FSMBehaviour;
|
||||
using Lean.Pool;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using UnityEngine.Playables;
|
||||
|
||||
namespace DemonBoss.Magic
|
||||
{
|
||||
/// <summary>
|
||||
/// Spawns a meteor behind the BOSS and launches it toward the player's position
|
||||
/// Similar mechanics to FireballProjectile but coming from above
|
||||
/// Spawns a meteor behind the BOSS and launches it toward the player's position.
|
||||
/// </summary>
|
||||
[CreateAssetMenu(menuName = "Invector/FSM/Actions/DemonBoss/Call Meteor")]
|
||||
public class SA_CallMeteor : vStateAction
|
||||
@@ -31,18 +32,37 @@ namespace DemonBoss.Magic
|
||||
[Tooltip("Tag used to find the target (usually Player)")]
|
||||
public string targetTag = "Player";
|
||||
|
||||
[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;
|
||||
|
||||
private Transform _boss;
|
||||
private Transform _target;
|
||||
|
||||
// --- Playables runtime ---
|
||||
private PlayableGraph _overlayGraph;
|
||||
|
||||
private AnimationPlayableOutput _overlayOutput;
|
||||
private AnimationClipPlayable _overlayPlayable;
|
||||
private bool _overlayPlaying;
|
||||
private float _overlayStopAtTime;
|
||||
|
||||
public override void DoAction(vIFSMBehaviourController fsm, vFSMComponentExecutionType execType = vFSMComponentExecutionType.OnStateUpdate)
|
||||
{
|
||||
if (execType == vFSMComponentExecutionType.OnStateEnter)
|
||||
{
|
||||
OnEnter(fsm);
|
||||
}
|
||||
else if (execType == vFSMComponentExecutionType.OnStateUpdate)
|
||||
{
|
||||
if (_overlayPlaying && Time.time >= _overlayStopAtTime) StopOverlayWithFade();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnter(vIFSMBehaviourController fsm)
|
||||
@@ -58,7 +78,14 @@ namespace DemonBoss.Magic
|
||||
|
||||
if (enableDebug) Debug.Log($"[SA_CallMeteor] Boss: {_boss.name}, Target: {_target.name}");
|
||||
|
||||
SpawnMeteor();
|
||||
// Fire overlay clip (no Animator params)
|
||||
PlayOverlayOnce(_boss);
|
||||
|
||||
// Optional: wait for castDelay before spawning (simple timer via Invoke)
|
||||
if (castDelay > 0f)
|
||||
_boss.gameObject.AddComponent<DelayedInvoker>().Init(castDelay, SpawnMeteor);
|
||||
else
|
||||
SpawnMeteor();
|
||||
}
|
||||
|
||||
private void SpawnMeteor()
|
||||
@@ -101,5 +128,79 @@ namespace DemonBoss.Magic
|
||||
if (enableDebug) Debug.LogError("[SA_CallMeteor] Meteor prefab missing MeteorProjectile component!");
|
||||
}
|
||||
}
|
||||
|
||||
// -------- Playables helpers (no Animator params) --------
|
||||
private void PlayOverlayOnce(Transform owner)
|
||||
{
|
||||
if (overlayClip == null) return;
|
||||
|
||||
var animator = owner.GetComponent<Animator>();
|
||||
if (animator == null) return;
|
||||
|
||||
StopOverlayImmediate();
|
||||
|
||||
_overlayGraph = PlayableGraph.Create("ActionOverlay(CallMeteor)");
|
||||
_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", animator);
|
||||
_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_CallMeteor] 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_CallMeteor] Overlay clip stopped");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tiny helper MonoBehaviour to delay a callback without coroutines here.
|
||||
/// </summary>
|
||||
private sealed class DelayedInvoker : MonoBehaviour
|
||||
{
|
||||
private float _timeLeft;
|
||||
private System.Action _callback;
|
||||
|
||||
public void Init(float delay, System.Action callback)
|
||||
{
|
||||
_timeLeft = delay;
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
_timeLeft -= Time.deltaTime;
|
||||
if (_timeLeft <= 0f)
|
||||
{
|
||||
try { _callback?.Invoke(); }
|
||||
finally { Destroy(this); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,187 +1,376 @@
|
||||
using Invector.vCharacterController.AI.FSMBehaviour;
|
||||
using Lean.Pool;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using UnityEngine.Playables;
|
||||
|
||||
namespace DemonBoss.Magic
|
||||
{
|
||||
/// <summary>
|
||||
/// StateAction for Magic Shield spell - boss casts magical shield for 5 seconds
|
||||
/// During casting boss stands still, after completion returns to Combat
|
||||
/// Magic Shield
|
||||
/// Spawns shield FX, holds for 'shieldDuration', then plays End and cleans up.
|
||||
/// </summary>
|
||||
[CreateAssetMenu(menuName = "Invector/FSM/Actions/DemonBoss/Cast Shield")]
|
||||
[CreateAssetMenu(menuName = "Invector/FSM/Actions/DemonBoss/Cast Shield (Start/Keep/End)")]
|
||||
public class SA_CastShield : vStateAction
|
||||
{
|
||||
public override string categoryName => "DemonBoss/Magic";
|
||||
public override string defaultName => "Cast Shield";
|
||||
|
||||
[Header("Shield Configuration")]
|
||||
[Header("Shield Logic")]
|
||||
[Tooltip("Prefab with magical shield particle effect")]
|
||||
public GameObject shieldFXPrefab;
|
||||
|
||||
[Tooltip("Shield duration in seconds")]
|
||||
[Tooltip("Shield duration in seconds (time spent in Keep phase before End)")]
|
||||
public float shieldDuration = 5f;
|
||||
|
||||
[Tooltip("Animator bool parameter name for blocking state")]
|
||||
[Tooltip("Animator bool parameter name for blocking state (optional)")]
|
||||
public string animatorBlockingBool = "IsBlocking";
|
||||
|
||||
[Header("Animation Clips (no Animator params)")]
|
||||
[Tooltip("One-shot intro")]
|
||||
public AnimationClip startClip;
|
||||
|
||||
[Tooltip("Looping hold/maintain")]
|
||||
public AnimationClip keepClip;
|
||||
|
||||
[Tooltip("One-shot outro")]
|
||||
public AnimationClip endClip;
|
||||
|
||||
[Header("Playback & Fades")]
|
||||
[Tooltip("Global playback speed for all clips")]
|
||||
public float clipSpeed = 1f;
|
||||
|
||||
[Tooltip("Seconds to crossfade between phases")]
|
||||
public float crossfadeTime = 0.12f;
|
||||
|
||||
[Tooltip("If the state exits early, still play End quickly before full teardown")]
|
||||
public bool playEndOnEarlyExit = true;
|
||||
|
||||
[Header("Debug")]
|
||||
[Tooltip("Enable debug logging")]
|
||||
public bool enableDebug = false;
|
||||
public bool debugLogs = false;
|
||||
|
||||
private GameObject spawnedShield;
|
||||
private Animator npcAnimator;
|
||||
private Transform npcTransform;
|
||||
private float shieldStartTime;
|
||||
private bool shieldActive = false;
|
||||
// --- Runtime (shield/FX) ---
|
||||
private Transform _npc;
|
||||
|
||||
/// <summary>
|
||||
/// Main action execution method called by FSM
|
||||
/// </summary>
|
||||
public override void DoAction(vIFSMBehaviourController fsmBehaviour, vFSMComponentExecutionType executionType = vFSMComponentExecutionType.OnStateUpdate)
|
||||
private Animator _anim;
|
||||
private GameObject _spawnedShieldFX;
|
||||
private float _shieldStartTime;
|
||||
private bool _shieldActive;
|
||||
|
||||
// --- Playables graph state ---
|
||||
private PlayableGraph _graph;
|
||||
|
||||
private AnimationPlayableOutput _output;
|
||||
private AnimationMixerPlayable _mixer; // 2-way mixer for crossfades
|
||||
|
||||
private AnimationClipPlayable _pStart;
|
||||
private AnimationClipPlayable _pKeep;
|
||||
private AnimationClipPlayable _pEnd;
|
||||
|
||||
private enum Phase
|
||||
{ None, Start, Keep, End, Done }
|
||||
|
||||
private Phase _phase = Phase.None;
|
||||
|
||||
// crossfade bookkeeping
|
||||
private int _fromInput = -1; // 0 or 1
|
||||
|
||||
private int _toInput = -1; // 0 or 1
|
||||
private float _fadeT0; // Time.time at fade start
|
||||
private float _fadeDur; // seconds
|
||||
private bool _fading;
|
||||
|
||||
// which clip is bound to each input
|
||||
private AnimationClipPlayable _input0;
|
||||
|
||||
private AnimationClipPlayable _input1;
|
||||
|
||||
// timers for auto-advance
|
||||
private float _phaseScheduledEnd = 0f; // absolute Time.time when Start/End should be done
|
||||
|
||||
public override void DoAction(vIFSMBehaviourController fsm, vFSMComponentExecutionType execType = vFSMComponentExecutionType.OnStateUpdate)
|
||||
{
|
||||
if (executionType == vFSMComponentExecutionType.OnStateEnter)
|
||||
if (execType == vFSMComponentExecutionType.OnStateEnter) OnEnter(fsm);
|
||||
else if (execType == vFSMComponentExecutionType.OnStateUpdate) OnUpdate(fsm);
|
||||
else if (execType == vFSMComponentExecutionType.OnStateExit) OnExit(fsm);
|
||||
}
|
||||
|
||||
// ------------------ FSM Hooks ------------------
|
||||
|
||||
private void OnEnter(vIFSMBehaviourController fsm)
|
||||
{
|
||||
_npc = fsm.transform;
|
||||
_anim = _npc.GetComponent<Animator>();
|
||||
|
||||
if (_anim != null && !string.IsNullOrEmpty(animatorBlockingBool))
|
||||
_anim.SetBool(animatorBlockingBool, true);
|
||||
|
||||
SpawnShieldFX();
|
||||
|
||||
_shieldStartTime = Time.time;
|
||||
_shieldActive = true;
|
||||
|
||||
BuildGraphIfNeeded();
|
||||
|
||||
if (startClip != null)
|
||||
{
|
||||
OnStateEnter(fsmBehaviour);
|
||||
EnterStart();
|
||||
}
|
||||
else if (executionType == vFSMComponentExecutionType.OnStateUpdate)
|
||||
else if (keepClip != null)
|
||||
{
|
||||
OnStateUpdate(fsmBehaviour);
|
||||
EnterKeep();
|
||||
}
|
||||
else if (executionType == vFSMComponentExecutionType.OnStateExit)
|
||||
else
|
||||
{
|
||||
OnStateExit(fsmBehaviour);
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] No Start/Keep clips; waiting to End.");
|
||||
_phase = Phase.Keep; // logical keep (no anim)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when entering state - starts shield casting
|
||||
/// </summary>
|
||||
private void OnStateEnter(vIFSMBehaviourController fsmBehaviour)
|
||||
private void OnUpdate(vIFSMBehaviourController fsm)
|
||||
{
|
||||
if (enableDebug) Debug.Log("[SA_CastShield] Entering shield casting state");
|
||||
|
||||
// Store NPC references
|
||||
npcTransform = fsmBehaviour.transform;
|
||||
npcAnimator = npcTransform.GetComponent<Animator>();
|
||||
|
||||
var aiController = fsmBehaviour as Invector.vCharacterController.AI.vIControlAI;
|
||||
if (aiController != null)
|
||||
// handle crossfade
|
||||
if (_fading)
|
||||
{
|
||||
aiController.Stop();
|
||||
if (enableDebug) Debug.Log("[SA_CastShield] AI stopped");
|
||||
float u = Mathf.Clamp01((Time.time - _fadeT0) / Mathf.Max(0.0001f, _fadeDur));
|
||||
if (_fromInput >= 0) _mixer.SetInputWeight(_fromInput, 1f - u);
|
||||
if (_toInput >= 0) _mixer.SetInputWeight(_toInput, u);
|
||||
if (u >= 1f) _fading = false;
|
||||
}
|
||||
|
||||
if (npcAnimator != null && !string.IsNullOrEmpty(animatorBlockingBool))
|
||||
// auto-advance phases based on timers
|
||||
if (_phase == Phase.Start && Time.time >= _phaseScheduledEnd)
|
||||
{
|
||||
npcAnimator.SetBool(animatorBlockingBool, true);
|
||||
if (enableDebug) Debug.Log($"[SA_CastShield] Set bool: {animatorBlockingBool} = true");
|
||||
if (keepClip != null) CrossfadeToKeep();
|
||||
else BeginEnd(); // no keep; go straight to End window
|
||||
}
|
||||
|
||||
SpawnShieldEffect(fsmBehaviour);
|
||||
|
||||
shieldStartTime = Time.time;
|
||||
shieldActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called every frame during state duration
|
||||
/// </summary>
|
||||
private void OnStateUpdate(vIFSMBehaviourController fsmBehaviour)
|
||||
{
|
||||
if (shieldActive && Time.time - shieldStartTime >= shieldDuration)
|
||||
else if (_phase == Phase.Keep)
|
||||
{
|
||||
if (enableDebug) Debug.Log("[SA_CastShield] Shield time passed, finishing state");
|
||||
FinishShield(fsmBehaviour);
|
||||
// When shield timer is up, begin End
|
||||
if (_shieldActive && (Time.time - _shieldStartTime) >= shieldDuration)
|
||||
{
|
||||
BeginEnd();
|
||||
}
|
||||
}
|
||||
else if (_phase == Phase.End && Time.time >= _phaseScheduledEnd)
|
||||
{
|
||||
// End completed
|
||||
_phase = Phase.Done;
|
||||
TeardownGraph();
|
||||
CleanupShieldFX();
|
||||
_shieldActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when exiting state - cleanup
|
||||
/// </summary>
|
||||
private void OnStateExit(vIFSMBehaviourController fsmBehaviour)
|
||||
private void OnExit(vIFSMBehaviourController fsm)
|
||||
{
|
||||
if (enableDebug) Debug.Log("[SA_CastShield] Exiting shield state");
|
||||
if (_anim != null && !string.IsNullOrEmpty(animatorBlockingBool))
|
||||
_anim.SetBool(animatorBlockingBool, false);
|
||||
|
||||
if (npcAnimator != null && !string.IsNullOrEmpty(animatorBlockingBool))
|
||||
// If we left early, optionally play End briefly (best-effort)
|
||||
if (playEndOnEarlyExit && _phase != Phase.End && _phase != Phase.Done && endClip != null)
|
||||
{
|
||||
npcAnimator.SetBool(animatorBlockingBool, false);
|
||||
if (enableDebug) Debug.Log($"[SA_CastShield] Set bool: {animatorBlockingBool} = false");
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] Early exit: playing End quickly.");
|
||||
// build graph if it was never built (e.g., no Start/Keep)
|
||||
BuildGraphIfNeeded();
|
||||
CrossfadeTo(endClip, out _pEnd, quick: true);
|
||||
_phase = Phase.End;
|
||||
_phaseScheduledEnd = Time.time + Mathf.Min(endClip.length / SafeSpeed(), 0.25f); // quick outro
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise normal cleanup
|
||||
TeardownGraph();
|
||||
}
|
||||
|
||||
if (shieldActive)
|
||||
{
|
||||
CleanupShield();
|
||||
}
|
||||
|
||||
var aiController = fsmBehaviour as Invector.vCharacterController.AI.vIControlAI;
|
||||
if (aiController != null)
|
||||
{
|
||||
if (enableDebug) Debug.Log("[SA_CastShield] AI resumed");
|
||||
}
|
||||
CleanupShieldFX();
|
||||
_shieldActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns magical shield particle effect
|
||||
/// </summary>
|
||||
private void SpawnShieldEffect(vIFSMBehaviourController fsmBehaviour)
|
||||
// ------------------ Phase Transitions ------------------
|
||||
|
||||
private void EnterStart()
|
||||
{
|
||||
if (shieldFXPrefab == null)
|
||||
CrossfadeTo(startClip, out _pStart, quick: false);
|
||||
_phase = Phase.Start;
|
||||
_phaseScheduledEnd = Time.time + (startClip.length / SafeSpeed());
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] Start phase.");
|
||||
}
|
||||
|
||||
private void CrossfadeToKeep()
|
||||
{
|
||||
if (keepClip == null)
|
||||
{
|
||||
Debug.LogWarning("[SA_CastShield] Missing shieldFXPrefab!");
|
||||
BeginEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
// Spawn shield at NPC's position and rotation
|
||||
Vector3 spawnPosition = npcTransform.position;
|
||||
Quaternion spawnRotation = npcTransform.rotation;
|
||||
|
||||
spawnedShield = LeanPool.Spawn(shieldFXPrefab, spawnPosition, spawnRotation);
|
||||
|
||||
if (enableDebug) Debug.Log($"[SA_CastShield] Shield spawned at NPC position: {spawnPosition}");
|
||||
CrossfadeTo(keepClip, out _pKeep, quick: false, loop: true);
|
||||
_phase = Phase.Keep;
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] Switched to Keep (loop).");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finishes shield operation and transitions to next state
|
||||
/// </summary>
|
||||
private void FinishShield(vIFSMBehaviourController fsmBehaviour)
|
||||
private void EnterKeep()
|
||||
{
|
||||
shieldActive = false;
|
||||
CleanupShield();
|
||||
|
||||
DEC_CheckCooldown.SetCooldownStatic(fsmBehaviour, "Shield", 15f);
|
||||
|
||||
// End state - FSM will transition to next state
|
||||
// FYI: In Invector FSM, state completion is handled automatically
|
||||
CrossfadeTo(keepClip, out _pKeep, quick: false, loop: true);
|
||||
_phase = Phase.Keep;
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] Entered Keep directly.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up spawned shield
|
||||
/// </summary>
|
||||
private void CleanupShield()
|
||||
private void BeginEnd()
|
||||
{
|
||||
if (spawnedShield != null)
|
||||
if (endClip == null)
|
||||
{
|
||||
LeanPool.Despawn(spawnedShield);
|
||||
spawnedShield = null;
|
||||
if (enableDebug) Debug.Log("[SA_CastShield] Shield despawned");
|
||||
// No end clip; just finish
|
||||
_phase = Phase.Done;
|
||||
TeardownGraph();
|
||||
CleanupShieldFX();
|
||||
_shieldActive = false;
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] No End clip; finished.");
|
||||
return;
|
||||
}
|
||||
CrossfadeTo(endClip, out _pEnd, quick: false);
|
||||
_phase = Phase.End;
|
||||
_phaseScheduledEnd = Time.time + (endClip.length / SafeSpeed());
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] End phase.");
|
||||
}
|
||||
|
||||
// ------------------ Graph Setup / Crossfade ------------------
|
||||
|
||||
private void BuildGraphIfNeeded()
|
||||
{
|
||||
if (_graph.IsValid()) return;
|
||||
|
||||
if (_anim == null)
|
||||
{
|
||||
_anim = _npc ? _npc.GetComponent<Animator>() : null;
|
||||
if (_anim == null)
|
||||
{
|
||||
if (debugLogs) Debug.LogWarning("[SA_CastShield] No Animator found; animation disabled.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_graph = PlayableGraph.Create("ShieldOverlayGraph");
|
||||
_graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
|
||||
|
||||
_mixer = AnimationMixerPlayable.Create(_graph, 2); // 2-way mixer
|
||||
_mixer.SetInputWeight(0, 0f);
|
||||
_mixer.SetInputWeight(1, 0f);
|
||||
|
||||
_output = AnimationPlayableOutput.Create(_graph, "AnimOut", _anim);
|
||||
_output.SetSourcePlayable(_mixer);
|
||||
_output.SetWeight(1f);
|
||||
|
||||
_graph.Play();
|
||||
}
|
||||
|
||||
private void TeardownGraph()
|
||||
{
|
||||
if (_graph.IsValid())
|
||||
{
|
||||
_graph.Stop();
|
||||
_graph.Destroy();
|
||||
}
|
||||
_input0 = default;
|
||||
_input1 = default;
|
||||
_fromInput = _toInput = -1;
|
||||
_fading = false;
|
||||
}
|
||||
|
||||
private float SafeSpeed() => Mathf.Max(0.0001f, clipSpeed);
|
||||
|
||||
/// <summary>
|
||||
/// Fades from whatever is currently audible to the given clip.
|
||||
/// Reuses the 2 inputs; swaps playables as needed.
|
||||
/// </summary>
|
||||
private void CrossfadeTo(AnimationClip clip,
|
||||
out AnimationClipPlayable playableOut,
|
||||
bool quick,
|
||||
bool loop = false)
|
||||
{
|
||||
playableOut = default;
|
||||
|
||||
if (!_graph.IsValid() || clip == null) return;
|
||||
|
||||
float speed = SafeSpeed();
|
||||
|
||||
// Prepare or reuse a slot (two inputs that we swap between)
|
||||
// Choose the silent input as target; if none is silent, pick the opposite of the currently "from".
|
||||
int targetInput = (_mixer.GetInputWeight(0) < 0.0001f) ? 0 : (_mixer.GetInputWeight(1) < 0.0001f) ? 1 : (_toInput == 0 ? 1 : 0);
|
||||
|
||||
// Destroy existing playable on that input if any
|
||||
var currentPlayableOnTarget = (AnimationClipPlayable)_mixer.GetInput(targetInput);
|
||||
if (currentPlayableOnTarget.IsValid())
|
||||
{
|
||||
_graph.Disconnect(_mixer, targetInput);
|
||||
currentPlayableOnTarget.Destroy();
|
||||
}
|
||||
|
||||
// Create new clip playable
|
||||
var newPlayable = AnimationClipPlayable.Create(_graph, clip);
|
||||
newPlayable.SetApplyFootIK(false);
|
||||
newPlayable.SetApplyPlayableIK(false);
|
||||
newPlayable.SetSpeed(speed);
|
||||
|
||||
// Connect to mixer
|
||||
_graph.Connect(newPlayable, 0, _mixer, targetInput);
|
||||
_mixer.SetInputWeight(targetInput, 0f);
|
||||
|
||||
// Cache which playable is on which slot for optional debug
|
||||
if (targetInput == 0) _input0 = newPlayable; else _input1 = newPlayable;
|
||||
|
||||
// Determine current audible input to fade from
|
||||
int sourceInput = (targetInput == 0) ? 1 : 0;
|
||||
float wSource = _mixer.GetInputWeight(sourceInput);
|
||||
bool hasSource = wSource > 0.0001f && _mixer.GetInput(sourceInput).IsValid();
|
||||
|
||||
// Start from beginning for new phase
|
||||
newPlayable.SetTime(0);
|
||||
playableOut = newPlayable;
|
||||
|
||||
// Configure fade
|
||||
_fromInput = hasSource ? sourceInput : -1;
|
||||
_toInput = targetInput;
|
||||
_fadeDur = Mathf.Max(0f, quick ? Mathf.Min(0.06f, crossfadeTime) : crossfadeTime);
|
||||
_fadeT0 = Time.time;
|
||||
_fading = _fadeDur > 0f && hasSource;
|
||||
|
||||
// Set immediate weights if not fading
|
||||
if (!_fading)
|
||||
{
|
||||
if (_fromInput >= 0) _mixer.SetInputWeight(_fromInput, 0f);
|
||||
_mixer.SetInputWeight(_toInput, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if shield is currently active
|
||||
/// </summary>
|
||||
public bool IsShieldActive()
|
||||
// ------------------ FX Helpers ------------------
|
||||
|
||||
private void SpawnShieldFX()
|
||||
{
|
||||
return shieldActive;
|
||||
if (shieldFXPrefab == null) return;
|
||||
_spawnedShieldFX = LeanPool.Spawn(shieldFXPrefab, _npc.position, _npc.rotation);
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] Shield FX spawned.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns remaining shield time
|
||||
/// </summary>
|
||||
private void CleanupShieldFX()
|
||||
{
|
||||
if (_spawnedShieldFX != null)
|
||||
{
|
||||
LeanPool.Despawn(_spawnedShieldFX);
|
||||
_spawnedShieldFX = null;
|
||||
if (debugLogs) Debug.Log("[SA_CastShield] Shield FX despawned.");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ Public Query ------------------
|
||||
|
||||
public bool IsShieldActive() => _shieldActive;
|
||||
|
||||
public float GetRemainingShieldTime()
|
||||
{
|
||||
if (!shieldActive) return 0f;
|
||||
return Mathf.Max(0f, shieldDuration - (Time.time - shieldStartTime));
|
||||
if (!_shieldActive) return 0f;
|
||||
float t = Mathf.Max(0f, shieldDuration - (Time.time - _shieldStartTime));
|
||||
return (_phase == Phase.End || _phase == Phase.Done) ? 0f : t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,13 @@ MonoBehaviour:
|
||||
type: 3}
|
||||
shieldDuration: 10
|
||||
animatorBlockingBool: IsBlocking
|
||||
enableDebug: 1
|
||||
startClip: {fileID: 7400082, guid: 3ef453d7877555243997dba1cdaa2958, type: 3}
|
||||
keepClip: {fileID: 7400084, guid: 3ef453d7877555243997dba1cdaa2958, type: 3}
|
||||
endClip: {fileID: 7400086, guid: 3ef453d7877555243997dba1cdaa2958, type: 3}
|
||||
clipSpeed: 1
|
||||
crossfadeTime: 0.12
|
||||
playEndOnEarlyExit: 1
|
||||
debugLogs: 0
|
||||
--- !u!114 &-6568372008305276654
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
@@ -158,11 +164,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: -445
|
||||
y: 30
|
||||
x: -595
|
||||
y: 70
|
||||
width: 150
|
||||
height: 62
|
||||
positionRect: {x: -445, y: 30}
|
||||
positionRect: {x: -595, y: 70}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 0, g: 1, b: 1, a: 1}
|
||||
@@ -189,14 +195,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -6568372008305276654}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -295
|
||||
y: 60
|
||||
x: -445
|
||||
y: 100
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -295
|
||||
y: 70
|
||||
x: -445
|
||||
y: 110
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -233,6 +239,10 @@ MonoBehaviour:
|
||||
aboveBossHeight: 20
|
||||
castDelay: 1.5
|
||||
targetTag: Player
|
||||
overlayClip: {fileID: 7400088, guid: 3ef453d7877555243997dba1cdaa2958, type: 3}
|
||||
overlaySpeed: 1
|
||||
overlayFadeIn: 0.1
|
||||
overlayFadeOut: 0.1
|
||||
enableDebug: 1
|
||||
--- !u!114 &-6379838510941931433
|
||||
MonoBehaviour:
|
||||
@@ -287,11 +297,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: -410
|
||||
y: 185
|
||||
x: -560
|
||||
y: 220
|
||||
width: 150
|
||||
height: 106
|
||||
positionRect: {x: -410, y: 185}
|
||||
positionRect: {x: -560, y: 220}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 0, b: 0, a: 1}
|
||||
@@ -318,14 +328,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -6144582714324757854}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -260
|
||||
y: 215
|
||||
x: -410
|
||||
y: 250
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -260
|
||||
y: 225
|
||||
x: -410
|
||||
y: 260
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -346,14 +356,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -6144582714324757854}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -260
|
||||
y: 237
|
||||
x: -410
|
||||
y: 272
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -260
|
||||
y: 247
|
||||
x: -410
|
||||
y: 282
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -382,14 +392,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -6144582714324757854}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -260
|
||||
y: 259
|
||||
x: -410
|
||||
y: 294
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -260
|
||||
y: 269
|
||||
x: -410
|
||||
y: 304
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -540,11 +550,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: -130
|
||||
y: 35
|
||||
x: -285
|
||||
y: 75
|
||||
width: 150
|
||||
height: 62
|
||||
positionRect: {x: -130, y: 35}
|
||||
positionRect: {x: -285, y: 75}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 0.10323405, g: 1, b: 0, a: 1}
|
||||
@@ -563,14 +573,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -3177478727897100882}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 20
|
||||
y: 65
|
||||
x: -135
|
||||
y: 105
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 20
|
||||
y: 75
|
||||
x: -135
|
||||
y: 115
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -609,11 +619,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: 165
|
||||
y: -5
|
||||
x: 0
|
||||
y: 35
|
||||
width: 150
|
||||
height: 62
|
||||
positionRect: {x: 165, y: -5}
|
||||
positionRect: {x: 0, y: 35}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 0, g: 1, b: 0.004989147, a: 1}
|
||||
@@ -625,7 +635,7 @@ MonoBehaviour:
|
||||
- decisions:
|
||||
- trueValue: 0
|
||||
decision: {fileID: 7927421991537792917}
|
||||
isValid: 0
|
||||
isValid: 1
|
||||
validated: 0
|
||||
trueState: {fileID: -312774025800194259}
|
||||
falseState: {fileID: 0}
|
||||
@@ -636,14 +646,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -2904979146780567904}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 155
|
||||
y: 25
|
||||
x: -10
|
||||
y: 65
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 315
|
||||
y: 35
|
||||
x: 150
|
||||
y: 75
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -751,6 +761,10 @@ MonoBehaviour:
|
||||
globalStartAngleRandom: 1
|
||||
perTurretAngleJitter: 10
|
||||
perTurretRadiusJitter: 0.75
|
||||
overlayClip: {fileID: 7400080, guid: 3ef453d7877555243997dba1cdaa2958, type: 3}
|
||||
overlaySpeed: 1
|
||||
overlayFadeIn: 0.1
|
||||
overlayFadeOut: 0.1
|
||||
enableDebug: 1
|
||||
showGizmos: 1
|
||||
--- !u!114 &-712571192746352845
|
||||
@@ -776,11 +790,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: -130
|
||||
y: -20
|
||||
x: -285
|
||||
y: 20
|
||||
width: 150
|
||||
height: 30
|
||||
positionRect: {x: -130, y: -20}
|
||||
positionRect: {x: -285, y: 20}
|
||||
rectWidth: 150
|
||||
editingName: 0
|
||||
nodeColor: {r: 0, g: 1, b: 0, a: 1}
|
||||
@@ -852,11 +866,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: -325
|
||||
y: 445
|
||||
x: -480
|
||||
y: 480
|
||||
width: 150
|
||||
height: 150
|
||||
positionRect: {x: -325, y: 445}
|
||||
positionRect: {x: -480, y: 480}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 0.95132554, b: 0, a: 1}
|
||||
@@ -883,14 +897,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -312774025800194259}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 475
|
||||
x: -330
|
||||
y: 510
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 485
|
||||
x: -330
|
||||
y: 520
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -915,14 +929,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -312774025800194259}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 497
|
||||
x: -330
|
||||
y: 532
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 507
|
||||
x: -330
|
||||
y: 542
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -955,14 +969,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -312774025800194259}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -335
|
||||
y: 519
|
||||
x: -490
|
||||
y: 554
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 529
|
||||
x: -330
|
||||
y: 564
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -991,14 +1005,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -312774025800194259}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 541
|
||||
x: -330
|
||||
y: 576
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 551
|
||||
x: -330
|
||||
y: 586
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1023,14 +1037,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: -312774025800194259}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 563
|
||||
x: -330
|
||||
y: 598
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: -175
|
||||
y: 573
|
||||
x: -330
|
||||
y: 608
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1077,7 +1091,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: a5fc604039227434d8b4e63ebc5e74a5, type: 3}
|
||||
m_Name: FSM_Demon
|
||||
m_EditorClassIdentifier:
|
||||
selectedNode: {fileID: 4162026404432437805}
|
||||
selectedNode: {fileID: 766956384951898899}
|
||||
wantConnection: 0
|
||||
connectionNode: {fileID: 0}
|
||||
showProperties: 1
|
||||
@@ -1094,7 +1108,7 @@ MonoBehaviour:
|
||||
- {fileID: 9112689765763526057}
|
||||
- {fileID: 766956384951898899}
|
||||
- {fileID: 4162026404432437805}
|
||||
panOffset: {x: -1205, y: 130}
|
||||
panOffset: {x: -860, y: -90}
|
||||
overNode: 0
|
||||
actions:
|
||||
- {fileID: 0}
|
||||
@@ -1178,11 +1192,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: 685
|
||||
y: 675
|
||||
x: 515
|
||||
y: 710
|
||||
width: 150
|
||||
height: 62
|
||||
positionRect: {x: 685, y: 675}
|
||||
positionRect: {x: 515, y: 710}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -1201,14 +1215,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 762670965814380212}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 675
|
||||
y: 705
|
||||
x: 505
|
||||
y: 740
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 835
|
||||
y: 715
|
||||
x: 665
|
||||
y: 750
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1245,14 +1259,14 @@ MonoBehaviour:
|
||||
canEditName: 1
|
||||
canEditColor: 1
|
||||
isOpen: 1
|
||||
isSelected: 0
|
||||
isSelected: 1
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: 750
|
||||
y: 125
|
||||
x: 580
|
||||
y: 165
|
||||
width: 150
|
||||
height: 62
|
||||
positionRect: {x: 750, y: 125}
|
||||
positionRect: {x: 580, y: 165}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -1271,14 +1285,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 766956384951898899}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 740
|
||||
y: 155
|
||||
x: 570
|
||||
y: 195
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 900
|
||||
y: 165
|
||||
x: 730
|
||||
y: 205
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1367,11 +1381,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: 475
|
||||
y: 675
|
||||
x: 305
|
||||
y: 710
|
||||
width: 150
|
||||
height: 62
|
||||
positionRect: {x: 475, y: 675}
|
||||
positionRect: {x: 305, y: 710}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -1390,14 +1404,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 2691300596403639167}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 465
|
||||
y: 705
|
||||
x: 295
|
||||
y: 740
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 625
|
||||
y: 715
|
||||
x: 455
|
||||
y: 750
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1437,11 +1451,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: 220
|
||||
y: 395
|
||||
x: 50
|
||||
y: 430
|
||||
width: 150
|
||||
height: 150
|
||||
positionRect: {x: 220, y: 395}
|
||||
positionRect: {x: 50, y: 430}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 0, b: 0, a: 1}
|
||||
@@ -1464,14 +1478,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 2986668563461644515}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 210
|
||||
y: 425
|
||||
x: 40
|
||||
y: 460
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 435
|
||||
x: 200
|
||||
y: 470
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1496,14 +1510,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 2986668563461644515}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 210
|
||||
y: 447
|
||||
x: 40
|
||||
y: 482
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 457
|
||||
x: 200
|
||||
y: 492
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1517,11 +1531,11 @@ MonoBehaviour:
|
||||
- decisions:
|
||||
- trueValue: 0
|
||||
decision: {fileID: -6379838510941931433}
|
||||
isValid: 0
|
||||
isValid: 1
|
||||
validated: 0
|
||||
- trueValue: 1
|
||||
decision: {fileID: -7938248970223304488}
|
||||
isValid: 1
|
||||
isValid: 0
|
||||
validated: 0
|
||||
trueState: {fileID: 766956384951898899}
|
||||
falseState: {fileID: 0}
|
||||
@@ -1532,14 +1546,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 2986668563461644515}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 469
|
||||
x: 200
|
||||
y: 504
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 479
|
||||
x: 200
|
||||
y: 514
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1553,7 +1567,7 @@ MonoBehaviour:
|
||||
- decisions:
|
||||
- trueValue: 0
|
||||
decision: {fileID: -6379838510941931433}
|
||||
isValid: 0
|
||||
isValid: 1
|
||||
validated: 0
|
||||
- trueValue: 1
|
||||
decision: {fileID: 8113515040269600600}
|
||||
@@ -1568,14 +1582,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 2986668563461644515}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 491
|
||||
x: 200
|
||||
y: 526
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 501
|
||||
x: 200
|
||||
y: 536
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1604,14 +1618,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 2986668563461644515}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 513
|
||||
x: 200
|
||||
y: 548
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 370
|
||||
y: 523
|
||||
x: 200
|
||||
y: 558
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
@@ -1708,14 +1722,14 @@ MonoBehaviour:
|
||||
canEditName: 1
|
||||
canEditColor: 1
|
||||
isOpen: 0
|
||||
isSelected: 1
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: 745
|
||||
y: 340
|
||||
x: 575
|
||||
y: 375
|
||||
width: 150
|
||||
height: 30
|
||||
positionRect: {x: 745, y: 340}
|
||||
positionRect: {x: 575, y: 375}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -1734,14 +1748,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 4162026404432437805}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 820
|
||||
y: 355
|
||||
x: 650
|
||||
y: 390
|
||||
width: 0
|
||||
height: 0
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 820
|
||||
y: 355
|
||||
x: 650
|
||||
y: 390
|
||||
width: 0
|
||||
height: 0
|
||||
selectedTrue: 0
|
||||
@@ -1907,11 +1921,11 @@ MonoBehaviour:
|
||||
isSelected: 0
|
||||
nodeRect:
|
||||
serializedVersion: 2
|
||||
x: 755
|
||||
y: -50
|
||||
x: 585
|
||||
y: -5
|
||||
width: 150
|
||||
height: 62
|
||||
positionRect: {x: 755, y: -50}
|
||||
positionRect: {x: 585, y: -5}
|
||||
rectWidth: 150
|
||||
editingName: 1
|
||||
nodeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -1930,14 +1944,14 @@ MonoBehaviour:
|
||||
parentState: {fileID: 9112689765763526057}
|
||||
trueRect:
|
||||
serializedVersion: 2
|
||||
x: 745
|
||||
y: -20
|
||||
x: 575
|
||||
y: 25
|
||||
width: 10
|
||||
height: 10
|
||||
falseRect:
|
||||
serializedVersion: 2
|
||||
x: 905
|
||||
y: -10
|
||||
x: 735
|
||||
y: 35
|
||||
width: 10
|
||||
height: 10
|
||||
selectedTrue: 0
|
||||
|
||||
@@ -18027,7 +18027,7 @@ BlendTree:
|
||||
m_Name: Run
|
||||
m_Childs:
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 7400012, guid: 37c6cfe59f56e8a4799011397a870a8b, type: 3}
|
||||
m_Motion: {fileID: 7400106, guid: 3ef453d7877555243997dba1cdaa2958, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 0, y: 1}
|
||||
m_TimeScale: 1
|
||||
@@ -18153,7 +18153,7 @@ BlendTree:
|
||||
m_DirectBlendParameter: InputHorizontal
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 7400012, guid: 37c6cfe59f56e8a4799011397a870a8b, type: 3}
|
||||
m_Motion: {fileID: 7400106, guid: 3ef453d7877555243997dba1cdaa2958, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 0, y: 0}
|
||||
m_TimeScale: 1
|
||||
@@ -34993,7 +34993,7 @@ AnimatorStateMachine:
|
||||
m_ChildStateMachines:
|
||||
- serializedVersion: 1
|
||||
m_StateMachine: {fileID: 1107736847571817844}
|
||||
m_Position: {x: 540, y: 192, z: 0}
|
||||
m_Position: {x: 540, y: 190, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_StateMachine: {fileID: 1107135120639222350}
|
||||
m_Position: {x: 324, y: 132, z: 0}
|
||||
|
||||
Reference in New Issue
Block a user