using System.Collections.Generic; using Snxxz.UI; using UnityEngine; public interface IFlyObject { bool Initialize(FlyObject.InitInfo initInfo); void Update(); bool IsOver(); void OnOver(); void UnInitialize(); } public abstract class FlyObject : IFlyObject { public class InitInfo { public Vector3 position; public Vector3 forward; public int skillId; public bool isLastShoot; public int configId; public uint casterServerObjID; public uint mainTargetClientInstID; } protected InitInfo m_InitInfo; protected List m_HurtClientList; protected List m_HurtServerList; protected List m_HasHitTargetIDList = new List(); protected Dictionary m_IdToLastHitTime = new Dictionary(); protected SoFlyObject m_Config; protected GActorFight m_Owner; protected Vector3 m_Position; protected Vector3 m_Direction; protected float m_HSpeed; protected float m_VSpeed; protected float m_StartTime; protected Vector3 m_MoveDistance; protected int m_HitCount; protected SFXController m_Ammo; public virtual bool Initialize(InitInfo initInfo) { m_HitCount = 0; m_StartTime = Time.time; m_MoveDistance = Vector3.zero; m_HasHitTargetIDList.Clear(); m_IdToLastHitTime.Clear(); m_InitInfo = initInfo; m_Position = initInfo.position; m_Direction = initInfo.forward; m_Config = ScriptableObjectLoader.LoadSoFlyObject(initInfo.configId); m_Owner = GAMgr.Instance.GetBySID(m_InitInfo.casterServerObjID) as GActorFight; if (m_Owner != null) { Skill _skill = m_Owner.SkillMgr.Get(m_InitInfo.skillId); m_HurtServerList = _skill.hurtServerList; m_HurtClientList = _skill.hurtClientList; if (m_HurtClientList.Count == 0) { m_HurtClientList = _skill.hurtServerList; } } else { m_MoveDistance = new Vector3(1000, 0, 1000); return false; } if (m_Config == null) { // 没有配置则回收对象 m_MoveDistance = new Vector3(1000, 0, 1000); return false; } PlayEffect(); #if UNITY_EDITOR SnxxzGame.Instance.AddOnDrawGizmosAction(OnDrawGizmos); #endif return true; } protected virtual void PlayEffect() { m_Ammo = SFXPlayUtility.Instance.Play(m_Config.ammoEffectId, m_Position, m_Direction); if (m_Ammo) { m_Ammo.duration = 0; m_Ammo.transform.position = m_Position; if (m_Direction != Vector3.zero) { m_Ammo.transform.forward = m_Direction; } } } protected virtual void MovingHitted() { if (m_HurtClientList == null) { return; } float _chkDistSqrt; GActorFight _target; for (int i = 0; i < m_HurtClientList.Count && m_HitCount < m_Config.maxHitCount; ++i) { _target = GAMgr.Instance.GetByCID(m_HurtClientList[i].clientInstID) as GActorFight; if (_target == null) { continue; } // 伤害间隔, 为0则对任何对象只伤害一次, 则之前伤害过的不再伤害 if (m_Config.hurtInterval == 0 && m_HasHitTargetIDList.Contains(m_HurtClientList[i].clientInstID)) { continue; } else { if (m_IdToLastHitTime.ContainsKey(_target.ClientInstID)) { if (Time.time - m_IdToLastHitTime[_target.ClientInstID] < m_Config.hurtInterval * Constants.F_GAMMA) { continue; } } } _chkDistSqrt = MathUtility.DistanceSqrtXZ(_target.Pos, m_Position); float _chkRange = .5f + m_Config.radius; if (_chkDistSqrt < _chkRange * _chkRange) { int _hurtValue = (int)(m_Config.floodPercent * Constants.F_DELTA * m_HurtClientList[i].HurtHP); AttackHandler.HandlerAttackTarget(m_Owner, _target, _hurtValue, m_HurtClientList[i].AttackType, m_InitInfo.skillId, m_InitInfo.configId, m_Config, _target.ActorInfo.serverDie); m_HasHitTargetIDList.Add(m_HurtClientList[i].clientInstID); m_IdToLastHitTime[_target.ClientInstID] = Time.time; m_HitCount += 1; } } for (int i = 0; i < m_HurtServerList.Count && m_HitCount < m_Config.maxHitCount; ++i) { _target = GAMgr.Instance.GetByCID(m_HurtServerList[i].clientInstID) as GActorFight; if (_target == null) { continue; } // 伤害间隔, 为0则对任何对象只伤害一次, 则之前伤害过的不再伤害 if (m_Config.hurtInterval == 0 && m_HasHitTargetIDList.Contains(m_HurtServerList[i].clientInstID)) { continue; } else { if (m_IdToLastHitTime.ContainsKey(_target.ClientInstID)) { if (Time.time - m_IdToLastHitTime[_target.ClientInstID] < m_Config.hurtInterval * Constants.F_GAMMA) { continue; } } } _chkDistSqrt = MathUtility.DistanceSqrtXZ(_target.Pos, m_Position); float _chkRange = .5f + m_Config.radius; if (_chkDistSqrt < _chkRange * _chkRange) { int _hurtValue = (int)(m_Config.floodPercent * Constants.F_DELTA * m_HurtServerList[i].HurtHP); AttackHandler.HandlerAttackTarget(m_Owner, _target, _hurtValue, m_HurtServerList[i].AttackType, m_InitInfo.skillId, m_InitInfo.configId, m_Config, _target.ActorInfo.serverDie); m_HasHitTargetIDList.Add(m_HurtServerList[i].clientInstID); m_IdToLastHitTime[_target.ClientInstID] = Time.time; m_HitCount += 1; } } } public void Update() { if (m_Config == null) { return; } OnUpdate(); MovingHitted(); } protected abstract void OnUpdate(); public virtual bool IsOver() { return m_Config.disppearWhenHitFinished && m_HitCount >= m_Config.maxHitCount; } public virtual void OnOver() { if (m_Config.blastEffectId != 0) { SFXPlayUtility.Instance.Play(m_Config.blastEffectId, m_Position, m_Direction); } } public virtual void UnInitialize() { m_Config = null; if (m_Ammo != null) { SFXPlayUtility.Instance.Release(m_Ammo); m_Ammo = null; } #if UNITY_EDITOR SnxxzGame.Instance.RemoveOnDrawGizmosAction(OnDrawGizmos); #endif } #if UNITY_EDITOR private void OnDrawGizmos() { OnDebugDraw(); } #endif protected virtual void OnDebugDraw() { } }