using CoreGame.Render; using GAS.General; using GAS.Runtime; using Sirenix.OdinInspector; using UnityEngine; using NotImplementedException = System.NotImplementedException; namespace CoreGame.Render { public class CueVFXOneShot : GameplayCueInstant { 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; public Quaternion LocalRotation => Quaternion.Euler(rotation); [ShowInInspector] [HideReferenceObjectPicker] [ShowIf("Cfg")] public RenderEffectDesc Cfg => RenderEffectDescMgr.Instance.GetConfig(effectId); public override GameplayCueInstantSpec CreateSpec(in GameplayCueParameters param) { var cueVFXOneShotSpec = SptPool.Malloc(); cueVFXOneShotSpec.Awake(param); return cueVFXOneShotSpec; } public override void FreeSpec(ref GameplayCueInstantSpec spec) { var cueVFXOneShotSpec = spec as CueVFXOneShotSpec; SptPool.Free(ref cueVFXOneShotSpec); spec = null; } #if UNITY_EDITOR private GameObject _effectPreviewInstance; public override void OnEditorPreview(GameObject previewObject, int frame, int startFrame) { if (effectId < 1) return; if (string.IsNullOrEmpty(Cfg.prefab)) return; var VfxPrefab = GameObjectUtil.LoadAssetAtPath(Cfg.prefab); if (frame >= startFrame) { if (_effectPreviewInstance != null && _effectPreviewInstance.name != VfxPrefab.name) { Object.DestroyImmediate(_effectPreviewInstance); _effectPreviewInstance = null; } if (_effectPreviewInstance == null) { _effectPreviewInstance = Object.Instantiate(VfxPrefab, previewObject.transform); _effectPreviewInstance.name = VfxPrefab.name; _effectPreviewInstance.transform.localPosition = offset; _effectPreviewInstance.transform.localEulerAngles = rotation; _effectPreviewInstance.transform.localScale = scale; } // 模拟例子的播放 var particleSystems = _effectPreviewInstance.GetComponentsInChildren(); foreach (var ps in particleSystems) { var t = (frame - startFrame) / GASTimer.FrameRate; ps.Simulate(t); } } else { if (_effectPreviewInstance != null) { Object.DestroyImmediate(_effectPreviewInstance); _effectPreviewInstance = null; } } } #endif } public class CueVFXOneShotSpec : GameplayCueInstantSpec { public override void Trigger() { 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); } } }