using System.Collections.Generic; using AOT; using CoreGame; using CoreGame; using Sirenix.OdinInspector; using Sog; using UnityEngine; using xFrame; namespace GAS.Runtime { public enum FillInType { None, AngleLerp, DistanceLerp, } public class WarningCue : GameplayCueDurational { public int geCatchTargetId; // 静态配置 public bool isFollowTargetRotation; // 是否跟随目标旋转 public int startChangeStateFrame; // 开始改变状态的帧数 public FillInType fillInType; // 填充类型 public string vfxPath = "Demo/VFX/WarningCue/CircleWarning.prefab"; // 特效路径 [ShowInInspector] [HideReferenceObjectPicker] [ShowIf("Cfg")] public GECatchTargetDesc Cfg => GECatchTargetDescMgr.Instance.GetConfig(geCatchTargetId); public override GameplayCueDurationalSpec CreateSpec(in GameplayCueParameters param) { var warningCueSpec = SptPool.Malloc(); warningCueSpec.Awake(param); return warningCueSpec; } public override void FreeSpec(ref GameplayCueDurationalSpec spec) { var warningCueSpec = spec as WarningCueSpec; SptPool.Free(ref warningCueSpec); spec = null; } } public class WaringCueInitData : ISptPool { public Vector2 position; public int entityId; public int geCatchTargetId; public void Awake(Vector2 position, int entityId, int geCatchTargetId) { this.position = position; this.entityId = entityId; this.geCatchTargetId = geCatchTargetId; } public void Reset() { } } public class WarningCueSpec : GameplayCueDurationalSpec { private Fixed64 m_StartChangeTime = 0; private Fixed64 m_timeAcc = 0; private Fixed64 m_durationInversed = 0; private List m_WarningGoDatas; private static readonly int s_Duration = Shader.PropertyToID("_Duration"); private static readonly int s_Angle = Shader.PropertyToID("_Angle"); public override void OnAdd() { m_WarningGoDatas = ListPool.Pop(); m_timeAcc = 0; var catchTarget = GECatchTargetDescMgr.Instance.GetConfig(cue.geCatchTargetId); if (catchTarget == null) { XLog.LogWarning("WarningCueSpec OnAdd m_CatchTarget is null"); } m_durationInversed = 1 / duration; if (cue.startChangeStateFrame > 0) { m_StartChangeTime = cue.startChangeStateFrame * TimelineRuntimeClipHelper.s_FrameTime; } // 预警目前之应用于ability if (initData.sourceGaSpec == null) { XLog.LogWarning("预警目前之应用于ability"); return; } var ctx = initData.sourceGaSpec.ctx; for (int i = 0; i < 1; i++) { var data = SptPool.Malloc(); // data.Awake(ctx.castPos[i], ctx.castTarget[i], cue.geCatchTargetId); // var goData = ownerEnt.GetNewGo(cue.vfxPath, OnLoad, data); // m_WarningGoDatas.Add(goData); } #if UNITY_EDITOR if (m_WarningGoDatas.Count == 0) { XLog.LogWarning("WarningCueSpec OnAdd m_WarningGoDatas is empty"); } #endif } // private void OnLoad(ReuseGoData reuseGoDatas) // { // var initData = (WaringCueInitData)reuseGoDatas.param; // var go = reuseGoDatas.go; // go.SetActiveWrap(true); // var geCatchTarget = GECatchTargetDescMgr.Instance.GetConfig(initData.geCatchTargetId); // var target = Contexts.Combat.GetEntity(initData.entityId); // var targetPos = initData.position; // if (target.IsValid()) // { // targetPos = target.transformProxy.position; // } // if (geCatchTarget.centerType == CenterType.Target) // { // go.transform.position = targetPos; // } // else // { // var srcPos = ownerEnt.transformProxy.position; // go.transform.position = srcPos; // go.transform.rotation = Quaternion.LookRotation(Vector3.forward, targetPos - srcPos); // } // go.transform.localScale = Vector3.one * (geCatchTarget.rangeRadius * BattleConst.TenThousandReverse * 2); // var spriteRenderer = go.GetComponent(); // var material = spriteRenderer.material; // if (cue.fillInType != FillInType.AngleLerp) // { // material.SetFloat(s_Angle, // Mathf.Floor(geCatchTarget.rangeAngle * BattleConst.TenThousandReverse + 0.5f)); // } // if (cue.fillInType != FillInType.DistanceLerp) // { // material.SetFloat(s_Duration, 1); // } // } public override void OnRemove() { for (int i = 0; i < m_WarningGoDatas.Count; i++) { var goData = m_WarningGoDatas[i]; var o = (WaringCueInitData)goData.param; goData.param = null; SptPool.Free(ref o); ownerEnt.ReleaseGo(goData); } ListPool.Push(ref m_WarningGoDatas); } public override void OnGameplayEffectActivate() { throw new System.NotImplementedException(); } public override void OnGameplayEffectDeactivate() { throw new System.NotImplementedException(); } public override void OnTick(Fixed64 dt) { m_timeAcc += dt; if (m_timeAcc >= m_StartChangeTime) { // 改变状态 // FillIn((m_timeAcc - m_StartChangeTime) * m_durationInversed); } else { LookAtTarget(); } } private void LookAtTarget() { } private void FillIn(float t) { if (cue.fillInType == FillInType.None) { return; } ReuseGoData goData; var geCatchTarget = GECatchTargetDescMgr.Instance.GetConfig(cue.geCatchTargetId); for (int i = 0; i < m_WarningGoDatas.Count; i++) { goData = m_WarningGoDatas[i]; if (goData.go == null) { continue; } var spriteRenderer = goData.go.GetComponent(); var material = spriteRenderer.material; if (cue.fillInType == FillInType.AngleLerp) { // var rangeAngle = Mathf.Lerp(0, // Mathf.Floor(geCatchTarget.rangeAngle * BattleConst.TenThousandReverse + 0.5f), t); // material.SetFloat(s_Angle, rangeAngle); } else if (cue.fillInType == FillInType.DistanceLerp) { material.SetFloat(s_Duration, Mathf.Lerp(0, 1, t)); } } } } }