You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
4.9 KiB

1 month ago
using System.Collections.Generic;
using CoreGame;
using CoreGame.Render;
using GAS.General;
using Sirenix.OdinInspector;
using Sog;
using UnityEngine;
using Object = UnityEngine.Object;
namespace GAS.Runtime
{
public class BindPointParam
{
public BindPointType type;
public string path;
}
public class CueVFX : GameplayCueDurational
{
public int effectId; // 静态配置
[BoxGroup] [LabelText(GASTextDefine.CUE_VFX_OFFSET)]
public Vector3 offset;
[BoxGroup] [LabelText(GASTextDefine.CUE_VFX_ROTATION)]
public Vector3 rotation;
[BoxGroup] [LabelText(GASTextDefine.CUE_VFX_SCALE)]
public Vector3 scale = Vector3.one;
[ShowInInspector]
[HideReferenceObjectPicker]
[ShowIf("Cfg")]
public RenderEffectDesc Cfg => RenderEffectDescMgr.Instance.GetConfig(effectId);
public Quaternion LocalRotation => Quaternion.Euler(rotation);
public override GameplayCueDurationalSpec CreateSpec(in GameplayCueParameters param)
{
var cueVFXSpec = SptPool<CueVFXSpec>.Malloc();
cueVFXSpec.Awake(param);
return cueVFXSpec;
}
public override void FreeSpec(ref GameplayCueDurationalSpec spec)
{
var cueVFXSpec = spec as CueVFXSpec;
SptPool<CueVFXSpec>.Free(ref cueVFXSpec);
spec = null;
}
#region 编辑
#if UNITY_EDITOR
private GameObject m_EffectPreviewInstance;
public CueVFX(string vfxPrefabPath, Vector3 offset, Vector3 rotation, int effectId)
{
this.offset = offset;
this.rotation = rotation;
this.effectId = effectId;
// VfxPrefabPath = vfxPrefabPath;
}
public override void OnEditorPreview(GameObject preview, int frameIndex, int startFrame, int endFrame)
{
if (effectId < 1)
return;
if (string.IsNullOrEmpty(Cfg.prefab)) return;
var VfxPrefab = GameObjectUtil.LoadAssetAtPath<GameObject>(Cfg.prefab);
if (frameIndex >= startFrame && frameIndex <= endFrame)
{
if (m_EffectPreviewInstance != null && m_EffectPreviewInstance.name != VfxPrefab.name)
{
Object.DestroyImmediate(m_EffectPreviewInstance);
m_EffectPreviewInstance = null;
}
if (m_EffectPreviewInstance == null)
{
m_EffectPreviewInstance = Object.Instantiate(VfxPrefab, preview.transform);
m_EffectPreviewInstance.name = VfxPrefab.name;
m_EffectPreviewInstance.transform.localPosition = offset;
m_EffectPreviewInstance.transform.localEulerAngles = rotation;
m_EffectPreviewInstance.transform.localScale = scale;
}
// 模拟例子的播放
var particleSystems = m_EffectPreviewInstance.GetComponentsInChildren<ParticleSystem>();
foreach (var ps in particleSystems)
{
var t = (frameIndex - startFrame) / GASTimer.FrameRate;
ps.Simulate(t);
}
}
else
{
if (m_EffectPreviewInstance != null)
{
Object.DestroyImmediate(m_EffectPreviewInstance);
m_EffectPreviewInstance = null;
}
}
}
#endif
}
#endregion
public class CueVFXSpec : GameplayCueDurationalSpec<CueVFX>
{
private GameObject m_VFXInstance;
private readonly List<int> m_EffectSeq = new();
public override void OnAdd()
{
if (cue.effectId < 1)
return;
var param = new TexiaoShowParam
{
effectId = cue.effectId,
offset = cue.offset,
rotation = cue.LocalRotation,
scale = cue.scale == Vector3.zero ? Vector3.one : cue.scale,
element = initData.sourceGaSpec != null
? initData.sourceGaSpec.gaParams.element
: initData.sourceGeSpec.effectParams.gaParams.element
};
ownerEnt.effectShowProxy.ShowCastEffect(ref param, initData, m_EffectSeq);
}
public override void OnRemove()
{
ownerEnt.effectShowProxy.DestroyEffect(m_EffectSeq);
}
public override void OnGameplayEffectActivate()
{
ownerEnt.effectShowProxy.ActivateEffect(m_EffectSeq);
}
public override void OnGameplayEffectDeactivate()
{
ownerEnt.effectShowProxy.DeactivateEffect(m_EffectSeq);
}
public override void OnTick(Fixed64 dt)
{
}
public void SetVisible(bool visible)
{
}
}
}