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.Malloc(); cueVFXSpec.Awake(param); return cueVFXSpec; } public override void FreeSpec(ref GameplayCueDurationalSpec spec) { var cueVFXSpec = spec as CueVFXSpec; SptPool.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(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(); 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 { private GameObject m_VFXInstance; private readonly List 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) { } } }