using UnityEngine; using System.Collections.Generic; using System; namespace BF { public class BattleControlWarning : MonoBehaviour { protected int uniqueId; protected BattleControlUnit owner; protected BattleControlUnit target; protected int warningType; // 预警形状 protected Vector2 warningStartDeflection; // 预警起点偏移 protected Vector2 warningEndDeflection; // 预警终点偏移 protected Vector2 warningRange; // 预警范围 protected float warningRadius; // 预警范围 protected float warningDelayTime; // 预警延迟时间 protected float warningDuration; // 预警时间 protected float warningTime; // 用于倒计时的预警时间 protected int warningTargetType; // 预警目标类型 protected BattleControlCollider followCollider; // 如果为追踪形预警,追踪的对象 protected Action luaOnBattleEventFunc; public SpriteRenderer outSp; public SpriteRenderer inSp; public BattleControlWarningCollider controlCollider; protected bool IsEnable = false; protected bool IsRecycle = false; protected int followColliderUniqueId = 0; public int GetUniqueId() { return uniqueId; } public bool GetIsEnable() { return IsEnable; } public bool GetIsRecycle() { return IsRecycle; } public void InitOwnerAndTarget(BattleControlUnit owner, BattleControlUnit target, int uniqueId) { this.owner = owner; this.target = target; this.uniqueId = uniqueId; } public void InitCircleWarning(int warningType, float deflectionX, float deflectionZ, float warningRadius, float warningDelayTime, float warningDuration, int warningTargetType) { this.warningType = warningType; this.warningStartDeflection = new Vector2(deflectionX, deflectionZ); this.warningEndDeflection = Vector2.zero; this.warningRange = Vector2.zero; this.warningRadius = warningRadius; this.warningDelayTime = warningDelayTime; this.warningDuration = warningDuration; this.warningTargetType = warningTargetType; this.followCollider = null; this.followColliderUniqueId = 0; this.warningTime = warningDelayTime + warningDuration; InitBase(); } public void InitRectWarning(int warningType, float startDeflectionX, float startDeflectionZ, float endDeflectionX, float endDeflectionZ, float warningRectX, float warningRectY, float warningDelayTime, float warningDuration, int warningTargetType) { this.warningType = warningType; this.warningStartDeflection = new Vector2(startDeflectionX, startDeflectionZ); this.warningEndDeflection = new Vector2(endDeflectionX, endDeflectionZ); this.warningRange = new Vector2(warningRectX, warningRectY); this.warningRadius = 0; this.warningDelayTime = warningDelayTime; this.warningDuration = warningDuration; this.warningTargetType = warningTargetType; this.followCollider = null; this.followColliderUniqueId = 0; this.warningTime = warningDelayTime + warningDuration; InitBase(); } public void InitFollowColliderWarning(int warningType, float deflectionX, float deflectionZ, float warningRadius, float warningDelayTime, float warningDuration, BattleControlCollider collider) { this.warningType = warningType; this.warningStartDeflection = new Vector2(deflectionX, deflectionZ); this.warningEndDeflection = Vector2.zero; this.warningRange = Vector2.zero; this.warningRadius = warningRadius; this.warningDelayTime = warningDelayTime; this.warningDuration = warningDuration; this.warningTargetType = 4; this.followCollider = collider; this.followColliderUniqueId = collider.GetUniqueId(); this.warningTime = warningDelayTime + warningDuration; InitBase(); } private void InitBase() { IsEnable = true; IsRecycle = false; var beginPos = Vector3.zero; var anglesZ = 0f; var outPos = Vector3.zero; var outRect = Vector2.zero; // 更新初始数据 if (warningTargetType == 1) // 目标为Hero { if (warningType == 1) // 矩形 { beginPos = owner.transform.position + new Vector3(warningStartDeflection.x, 0, warningStartDeflection.y); var targetPos = target.transform.position; var diffPos = targetPos - beginPos; anglesZ = Vector2.Angle(Vector2.right, new Vector2(diffPos.x, diffPos.z)); if (targetPos.z < beginPos.z) { anglesZ = -anglesZ; } } else // 圆形 { beginPos = target.transform.position + new Vector3(warningStartDeflection.x, 0, warningStartDeflection.y); } } else if (warningTargetType == 2) // 目标为自身 { beginPos = owner.transform.position + new Vector3(warningStartDeflection.x, 0, warningStartDeflection.y); anglesZ = owner.Direction == 1 ? 0f : 180f; } else if (warningTargetType == 3) // 目标为场景 { beginPos = new Vector3(warningStartDeflection.x, 0, warningStartDeflection.y); anglesZ = Vector2.Angle(Vector2.right, warningStartDeflection - warningEndDeflection); if (warningEndDeflection.y < warningStartDeflection.y) { anglesZ = -anglesZ; } } else if (warningTargetType == 4) // 目标为子弹 { if (!ReferenceEquals(followCollider, null)) { beginPos = followCollider.transform.position; } } if (warningType == 1) // 矩形 { outPos = new Vector3(warningRange.x / 2, 0, 0); outRect = warningRange; } else if (warningType == 2) // 圆形 { outPos = Vector3.zero; outRect = new Vector2(warningRadius, warningRadius); } // 设置初始位置,朝向,大小 transform.position = beginPos; transform.eulerAngles = new Vector3(90, 0, anglesZ); outSp.transform.localPosition = outPos; outSp.size = outRect; inSp.transform.localPosition = outPos + new Vector3(0, 0.01f, 0); // 初始先隐藏 inSp.enabled = false; outSp.enabled = false; //初始化collider controlCollider.InitWarningType(this, warningType); if (warningType == 1) { controlCollider.boxCollider.center = outPos; controlCollider.boxCollider.size = outRect; } else if (warningType == 2) { controlCollider.sphereCollider.center = Vector3.zero; controlCollider.sphereCollider.radius = warningRadius / 2; } controlCollider.SetColliderDisable(); BFMain.Instance.BattleMgr.RemoveEffectWarning(GetUniqueId()); } private void Update() { if (IsEnable) { warningTime -= Time.deltaTime * BattleConfigure.TimeScale; if (warningTime < 0.0f) { Recycle(); return; } // 表现逻辑 if ((warningDuration < warningTime) && warningTime < (warningDelayTime + warningDuration)) // 延迟生效 { //隐藏 inSp.enabled = false; outSp.enabled = false; } else if ((0 < warningTime) && (warningTime < warningDuration)) // 正常缩放表现 { inSp.enabled = true; outSp.enabled = true; var rate = 1 - warningTime / warningDuration; rate = UnityEngine.Mathf.Clamp(rate, 0, 1); if (warningType == 1) // 矩形 { inSp.transform.localPosition = new Vector3(rate * warningRange.x / 2, 0, -0.01f); inSp.size = new Vector2(rate * warningRange.x, warningRange.y); } else { inSp.size = new Vector2(rate * warningRadius, rate * warningRadius); } //设置Collider 有效 controlCollider.SetColliderEnable(); BFMain.Instance.BattleMgr.AddEffectWarning(GetUniqueId()); } if (warningTargetType == 4) // 跟踪子弹 { if (!ReferenceEquals(followCollider, null)) { this.transform.position = followCollider.transform.position; } if (followCollider.GetUniqueId() != followColliderUniqueId) { Recycle(); return; } } } } public void Recycle() { OnBattleEvent(1); // 回调Lua触发回收 IsEnable = false; IsRecycle = true; this.controlCollider.SetColliderDisable(); this.owner = null; this.target = null; luaOnBattleEventFunc = null; BFMain.Instance.BattleMgr.RemoveEffectHeroWarning(uniqueId); BFMain.Instance.BattleMgr.RemoveEffectWarning(GetUniqueId()); } public void AddLuaOnBattleEvent(Action luaFunc) { luaOnBattleEventFunc = luaFunc; } public void OnBattleEvent(int eventType) { luaOnBattleEventFunc?.Invoke(eventType); } } }