Files
Cielonos/Assets/Scripts/MainGame/Effects/Feedbacks/Actions/VFX/SpawnVfxAction.cs
SoulliesOfficial 9a9e48f8a5
2026-06-27 12:52:03 -04:00

84 lines
2.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
using SLSUtilities.Feedback;
using Cielonos.MainGame.Characters;
using Lean.Pool;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 特效生成反馈动作,在 Feedback 轨道上生成指定的 VFX 特效。
/// 自动根据执行者的 VFXData 配置进行位置偏移、绑定关系处理。
/// </summary>
[Serializable]
[FeedbackActionColor(0.8f, 0.4f, 0.7f)]
public class SpawnVfxAction : FeedbackActionBase
{
public override string DisplayName => "Spawn VFX";
[Required]
[Tooltip("特效的 Key 名称,需在角色的 VFXData 配置文件中注册")]
public string vfxName;
[LabelText("被打断时停止")]
[Tooltip("如果为 true当反馈轨道被打断如受击、格挡此特效粒子会被立即回收/停止播放。")]
public bool stopOnInterrupt = true;
// 运行时状态记录,使用 Dictionary 保证并发/多角色播放时的实例安全
private readonly Dictionary<FeedbackPlayer, GameObject> _spawnedVFX = new Dictionary<FeedbackPlayer, GameObject>();
public override void OnStart(FeedbackContext context)
{
if (string.IsNullOrEmpty(vfxName) || context.owner == null) return;
CharacterBase character = context.owner.GetComponent<CharacterBase>();
if (character != null && character.vfxData != null)
{
GameObject vfxInstance = character.vfxData.SpawnVFX(vfxName, character, context.owner);
if (vfxInstance != null)
{
_spawnedVFX[context.player] = vfxInstance;
}
}
}
public override void OnInterrupt(FeedbackContext context)
{
if (stopOnInterrupt)
{
if (_spawnedVFX.TryGetValue(context.player, out GameObject vfxInstance))
{
if (vfxInstance != null)
{
LeanPool.Despawn(vfxInstance);
}
}
}
Cleanup(context);
}
public override void OnEnd(FeedbackContext context)
{
Cleanup(context);
}
private void Cleanup(FeedbackContext context)
{
_spawnedVFX.Remove(context.player);
}
public override bool Validate(out string error)
{
if (string.IsNullOrEmpty(vfxName))
{
error = "VFX Name is not assigned.";
return false;
}
error = null;
return true;
}
}
}