using System; using Continentis.MainGame.Character; using Cysharp.Threading.Tasks; using Lean.Pool; using SLSFramework.General; using SLSFramework.UModAssistance; using UnityEngine; namespace Continentis.MainGame.Commands { public class Cmd_SpawnVFX : CommandBase { private readonly VisualEffectBase vfxPrefab; private readonly CharacterBase target; private readonly Vector3 fixedPosition; private readonly Vector3 positionOffset; private readonly bool willWaitUntilFinish; private readonly float overrideDuration; /// 在目标角色位置生成 VFX。 public Cmd_SpawnVFX(string vfxID, CharacterBase target, Vector3 positionOffset = default, bool willWaitUntilFinish = false, float overrideDuration = -1f) { this.vfxPrefab = ModManager.GetAsset(vfxID).GetComponent(); this.target = target; this.positionOffset = positionOffset; this.fixedPosition = Vector3.zero; this.willWaitUntilFinish = willWaitUntilFinish; this.overrideDuration = overrideDuration; } /// 在世界坐标固定位置生成 VFX。 public Cmd_SpawnVFX(string vfxID, Vector3 position = default, bool willWaitUntilFinish = false, float overrideDuration = -1f) { this.vfxPrefab = ModManager.GetAsset(vfxID).GetComponent(); this.target = null; this.fixedPosition = position; this.positionOffset = Vector3.zero; this.willWaitUntilFinish = willWaitUntilFinish; this.overrideDuration = overrideDuration; } /// 在目标角色位置生成 VFX(直接传入 Prefab GameObject)。 public Cmd_SpawnVFX(GameObject prefab, CharacterBase target, Vector3 positionOffset = default, bool willWaitUntilFinish = false, float overrideDuration = -1f) { this.vfxPrefab = prefab.GetComponent(); this.target = target; this.positionOffset = positionOffset; this.fixedPosition = Vector3.zero; this.willWaitUntilFinish = willWaitUntilFinish; this.overrideDuration = overrideDuration; } /// 在世界坐标固定位置生成 VFX(直接传入 Prefab GameObject)。 public Cmd_SpawnVFX(GameObject prefab, Vector3 position = default, bool willWaitUntilFinish = false, float overrideDuration = -1f) { this.vfxPrefab = prefab.GetComponent(); this.target = null; this.fixedPosition = position; this.positionOffset = Vector3.zero; this.willWaitUntilFinish = willWaitUntilFinish; this.overrideDuration = overrideDuration; } protected override async UniTask ExecuteAsync(CommandContext outerContext) { if (vfxPrefab == null) { Debug.LogWarning("[Cmd_SpawnVFX] VFX Prefab 为空。"); return; } Vector3 spawnPosition = target != null ? target.characterView.centerPoint.transform.position + positionOffset : fixedPosition; VisualEffectBase spawnedVFX = LeanPool.Spawn(vfxPrefab, spawnPosition, Quaternion.identity); if (!spawnedVFX.isAutoDespawn) Debug.LogWarning("[Cmd_SpawnVFX] 生成的 VFX 未设置自动销毁,可能导致内存泄漏。"); if (willWaitUntilFinish) { float duration = overrideDuration > 0f ? overrideDuration : spawnedVFX.autoDespawnTime; await UniTask.Delay(TimeSpan.FromSeconds(duration)); } } } }