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<AttackHandler.HurtObjs> m_HurtClientList;
|
protected List<AttackHandler.HurtObjs> m_HurtServerList;
|
protected List<uint> m_HasHitTargetIDList = new List<uint>();
|
protected Dictionary<uint, float> m_IdToLastHitTime = new Dictionary<uint, float>();
|
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() { }
|
|
}
|