架构大更
This commit is contained in:
@@ -1,99 +1,91 @@
|
||||
using System;
|
||||
using Continentis.MainGame.Character;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Lean.Pool;
|
||||
using SLSFramework.General;
|
||||
using SLSFramework.UModAssistance;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Continentis.MainGame.Commands
|
||||
{
|
||||
public class Cmd_SpawnVFX : CommandBase
|
||||
{
|
||||
public VisualEffectBase vfxPrefab;
|
||||
public bool useTargetPosition;
|
||||
public Vector3 spawnPosition;
|
||||
public Vector3 spawnPositionOffset;
|
||||
public bool willWaitUntilFinish;
|
||||
public float overrideDuration;
|
||||
|
||||
|
||||
public Cmd_SpawnVFX(string vfxID, bool useTargetPosition = true, Vector3 positionOrOffset = default,
|
||||
bool willWaitUntilFinish = false, float overrideDuration = -1f) : base(null)
|
||||
private readonly VisualEffectBase vfxPrefab;
|
||||
private readonly CharacterBase target;
|
||||
private readonly Vector3 fixedPosition;
|
||||
private readonly Vector3 positionOffset;
|
||||
private readonly bool willWaitUntilFinish;
|
||||
private readonly float overrideDuration;
|
||||
|
||||
/// <summary>在目标角色位置生成 VFX。</summary>
|
||||
public Cmd_SpawnVFX(string vfxID, CharacterBase target, Vector3 positionOffset = default,
|
||||
bool willWaitUntilFinish = false, float overrideDuration = -1f)
|
||||
{
|
||||
this.vfxPrefab = ModManager.GetAsset<GameObject>(vfxID).GetComponent<VisualEffectBase>();
|
||||
this.useTargetPosition = useTargetPosition;
|
||||
|
||||
if (useTargetPosition)
|
||||
{
|
||||
this.spawnPosition = Vector3.zero;
|
||||
this.spawnPositionOffset = positionOrOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.spawnPosition = positionOrOffset;
|
||||
this.spawnPositionOffset = Vector3.zero;
|
||||
}
|
||||
|
||||
this.target = target;
|
||||
this.positionOffset = positionOffset;
|
||||
this.fixedPosition = Vector3.zero;
|
||||
this.willWaitUntilFinish = willWaitUntilFinish;
|
||||
this.overrideDuration = overrideDuration;
|
||||
}
|
||||
|
||||
public Cmd_SpawnVFX(GameObject prefab, bool useTargetPosition = true, Vector3 positionOrOffset = default,
|
||||
bool willWaitUntilFinish = false, float overrideDuration = -1f) : base(null)
|
||||
|
||||
/// <summary>在世界坐标固定位置生成 VFX。</summary>
|
||||
public Cmd_SpawnVFX(string vfxID, Vector3 position = default,
|
||||
bool willWaitUntilFinish = false, float overrideDuration = -1f)
|
||||
{
|
||||
this.vfxPrefab = ModManager.GetAsset<GameObject>(vfxID).GetComponent<VisualEffectBase>();
|
||||
this.target = null;
|
||||
this.fixedPosition = position;
|
||||
this.positionOffset = Vector3.zero;
|
||||
this.willWaitUntilFinish = willWaitUntilFinish;
|
||||
this.overrideDuration = overrideDuration;
|
||||
}
|
||||
|
||||
/// <summary>在目标角色位置生成 VFX(直接传入 Prefab GameObject)。</summary>
|
||||
public Cmd_SpawnVFX(GameObject prefab, CharacterBase target, Vector3 positionOffset = default,
|
||||
bool willWaitUntilFinish = false, float overrideDuration = -1f)
|
||||
{
|
||||
this.vfxPrefab = prefab.GetComponent<VisualEffectBase>();
|
||||
this.useTargetPosition = useTargetPosition;
|
||||
|
||||
if (useTargetPosition)
|
||||
{
|
||||
this.spawnPosition = Vector3.zero;
|
||||
this.spawnPositionOffset = positionOrOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.spawnPosition = positionOrOffset;
|
||||
this.spawnPositionOffset = Vector3.zero;
|
||||
}
|
||||
|
||||
this.target = target;
|
||||
this.positionOffset = positionOffset;
|
||||
this.fixedPosition = Vector3.zero;
|
||||
this.willWaitUntilFinish = willWaitUntilFinish;
|
||||
this.overrideDuration = overrideDuration;
|
||||
}
|
||||
|
||||
protected override IObservable<Unit> OnExecute(CommandContext outerContext)
|
||||
|
||||
/// <summary>在世界坐标固定位置生成 VFX(直接传入 Prefab GameObject)。</summary>
|
||||
public Cmd_SpawnVFX(GameObject prefab, Vector3 position = default,
|
||||
bool willWaitUntilFinish = false, float overrideDuration = -1f)
|
||||
{
|
||||
this.vfxPrefab = prefab.GetComponent<VisualEffectBase>();
|
||||
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("VFX Prefab is null.");
|
||||
return Observable.Return(Unit.Default);
|
||||
Debug.LogWarning("[Cmd_SpawnVFX] VFX Prefab 为空。");
|
||||
return;
|
||||
}
|
||||
|
||||
return base.OnExecute(outerContext);
|
||||
}
|
||||
|
||||
protected override IObservable<Unit> CoreExecute(CommandContext outerContext)
|
||||
{
|
||||
if (useTargetPosition)
|
||||
{
|
||||
if (selfContext.context["Target"] is CharacterBase character)
|
||||
{
|
||||
spawnPosition = character.characterView.centerPoint.transform.position;
|
||||
}
|
||||
}
|
||||
|
||||
VisualEffectBase spawnedVFX = LeanPool.Spawn(vfxPrefab, spawnPosition + spawnPositionOffset, Quaternion.identity);
|
||||
|
||||
if(!spawnedVFX.isAutoDespawn) Debug.LogWarning("Spawned VFX is not set to auto-despawn. This may lead to memory leaks.");
|
||||
|
||||
float vfxDuration = overrideDuration > 0 ? overrideDuration : spawnedVFX.autoDespawnTime;
|
||||
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)
|
||||
{
|
||||
return Observable.Timer(TimeSpan.FromSeconds(vfxDuration)).AsUnitObservable();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Observable.Return(Unit.Default);
|
||||
float duration = overrideDuration > 0f ? overrideDuration : spawnedVFX.autoDespawnTime;
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user