From b01151f932f8faa041a8facfb03059147170f40c Mon Sep 17 00:00:00 2001 From: liuzhiwei <liuzhiwei@qq.com> Date: Wed, 09 Dec 2020 10:16:24 +0800 Subject: [PATCH] Merge branch 'master' of http://172.16.1.52:8090/r/GemBattle into master --- Assets/Scripts/TowerDefense/Targetting/Targetter.cs | 810 ++++++++++++++++++++++++++++---------------------------- 1 files changed, 405 insertions(+), 405 deletions(-) diff --git a/Assets/Scripts/TowerDefense/Targetting/Targetter.cs b/Assets/Scripts/TowerDefense/Targetting/Targetter.cs index e4c35b9..97d7677 100644 --- a/Assets/Scripts/TowerDefense/Targetting/Targetter.cs +++ b/Assets/Scripts/TowerDefense/Targetting/Targetter.cs @@ -10,470 +10,470 @@ namespace TowerDefense.Targetting { - /// <summary> - /// 选择目标Agent的方式 - /// </summary> - public enum EEnemySelFunc - { - NULL, - Nearest, // 离终点最近的. - Random, // 随机选择. - MaxHp, // 血量最高的. - END - } - /// <summary> - /// Class used to track targets for an affector - /// 这个类比较古怪的地方是他本身并没有显示出来Collider,但却有Collider Component.是在 - /// void AttachCollider() 这个函数中(TargetterEditor.cs),动态的添加了不同类型的Collider Component, - /// 然后隐藏了这个Collider Component,但是却可以在游戏内当作Collider Component来使用。 - /// 在TargetterEditor内,设置isTrigger为true - /// - /// event 的作用在于声明的对应公有 Action or delegate变量,不能在类的外面执行,只在类的外面 += -= 操作 - /// - /// </summary> - public class Targetter : MonoBehaviour - { - public static bool bSearchTarget = true; - /// <summary> - /// Fires when a targetable enters the target collider - /// </summary> - public event Action<Targetable> targetEntersRange; + /// <summary> + /// 选择目标Agent的方式 + /// </summary> + public enum EEnemySelFunc + { + NULL, + Nearest, // 离终点最近的. + Random, // 随机选择. + MaxHp, // 血量最高的. + END + } + /// <summary> + /// Class used to track targets for an affector + /// 这个类比较古怪的地方是他本身并没有显示出来Collider,但却有Collider Component.是在 + /// void AttachCollider() 这个函数中(TargetterEditor.cs),动态的添加了不同类型的Collider Component, + /// 然后隐藏了这个Collider Component,但是却可以在游戏内当作Collider Component来使用。 + /// 在TargetterEditor内,设置isTrigger为true + /// + /// event 的作用在于声明的对应公有 Action or delegate变量,不能在类的外面执行,只在类的外面 += -= 操作 + /// + /// </summary> + public class Targetter : MonoBehaviour + { + public static bool bSearchTarget = true; + /// <summary> + /// Fires when a targetable enters the target collider + /// </summary> + public event Action<Targetable> targetEntersRange; - /// <summary> - /// Fires when a targetable exits the target collider - /// </summary> - public event Action<Targetable> targetExitsRange; + /// <summary> + /// Fires when a targetable exits the target collider + /// </summary> + public event Action<Targetable> targetExitsRange; - /// <summary> - /// Fires when an appropriate target is found - /// </summary> - public event Action<Targetable> acquiredTarget; + /// <summary> + /// Fires when an appropriate target is found + /// </summary> + public event Action<Targetable> acquiredTarget; - /// <summary> - /// Fires when the current target was lost - /// </summary> - public event Action lostTarget; + /// <summary> + /// Fires when the current target was lost + /// </summary> + public event Action lostTarget; - /// <summary> - /// The transform to point at the target - /// </summary> - public Transform turret; + /// <summary> + /// The transform to point at the target + /// </summary> + public Transform turret; - /// <summary> - /// 搜索敌人的方式:默认是最近,加入随机和血量最多,后期再加其它的模式 - /// </summary> - public EEnemySelFunc searchEnemyFunc = EEnemySelFunc.Nearest; + /// <summary> + /// 搜索敌人的方式:默认是最近,加入随机和血量最多,后期再加其它的模式 + /// </summary> + public EEnemySelFunc searchEnemyFunc = EEnemySelFunc.Nearest; - /// <summary> - /// The range of the turret's x rotation - /// </summary> - public Vector2 turretXRotationRange = new Vector2(0, 359); + /// <summary> + /// The range of the turret's x rotation + /// </summary> + public Vector2 turretXRotationRange = new Vector2(0, 359); - /// <summary> - /// If m_Turret rotates freely or only on y; - /// </summary> - public bool onlyYTurretRotation; + /// <summary> + /// If m_Turret rotates freely or only on y; + /// </summary> + public bool onlyYTurretRotation; - /// <summary> - /// The search rate in searches per second - /// </summary> - public float searchRate; + /// <summary> + /// The search rate in searches per second + /// </summary> + public float searchRate; - /// <summary> - /// Y rotation speed while the turret is idle in degrees per second - /// </summary> - public float idleRotationSpeed = 39f; + /// <summary> + /// Y rotation speed while the turret is idle in degrees per second + /// </summary> + public float idleRotationSpeed = 39f; - /// <summary> - /// The time it takes for the tower to correct its x rotation on idle in seconds - /// </summary> - public float idleCorrectionTime = 2.0f; + /// <summary> + /// The time it takes for the tower to correct its x rotation on idle in seconds + /// </summary> + public float idleCorrectionTime = 2.0f; - /// <summary> - /// The collider attached to the targetter - /// </summary> - public Collider attachedCollider; + /// <summary> + /// The collider attached to the targetter + /// </summary> + public Collider attachedCollider; - /// <summary> - /// How long the turret waits in its idle form before spinning in seconds - /// </summary> - public float idleWaitTime = 2.0f; + /// <summary> + /// How long the turret waits in its idle form before spinning in seconds + /// </summary> + public float idleWaitTime = 2.0f; - /// <summary> - /// The current targetables in the collider - /// </summary> - protected List<Targetable> m_TargetsInRange = new List<Targetable>(); + /// <summary> + /// The current targetables in the collider + /// </summary> + protected List<Targetable> m_TargetsInRange = new List<Targetable>(); - /// <summary> - /// The seconds until a search is allowed - /// </summary> - protected float m_SearchTimer = 0.0f; + /// <summary> + /// The seconds until a search is allowed + /// </summary> + protected float m_SearchTimer = 0.0f; - /// <summary> - /// The seconds until the tower starts spinning - /// </summary> - protected float m_WaitTimer = 0.0f; + /// <summary> + /// The seconds until the tower starts spinning + /// </summary> + protected float m_WaitTimer = 0.0f; - /// <summary> - /// The current targetable - /// </summary> - protected Targetable m_CurrrentTargetable; + /// <summary> + /// The current targetable + /// </summary> + protected Targetable m_CurrrentTargetable; - /// <summary> - /// Counter used for x rotation correction - /// </summary> - protected float m_XRotationCorrectionTime; + /// <summary> + /// Counter used for x rotation correction + /// </summary> + protected float m_XRotationCorrectionTime; - /// <summary> - /// If there was a targetable in the last frame - /// </summary> - protected bool m_HadTarget; + /// <summary> + /// If there was a targetable in the last frame + /// </summary> + protected bool m_HadTarget; - /// <summary> - /// How fast this turret is spinning - /// </summary> - protected float m_CurrentRotationSpeed; + /// <summary> + /// How fast this turret is spinning + /// </summary> + protected float m_CurrentRotationSpeed; - /// <summary> - /// returns the radius of the collider whether - /// its a sphere or capsule - /// </summary> - public float effectRadius - { - get - { - var sphere = attachedCollider as SphereCollider; - if (sphere != null) - { - return sphere.radius; - } - var capsule = attachedCollider as CapsuleCollider; - if (capsule != null) - { - return capsule.radius; - } - return 0; - } - } - - /// <summary> - /// The alignment of the affector - /// </summary> - public IAlignmentProvider alignment; - - /// <summary> - /// Returns the current target - /// </summary> - public Targetable GetTarget( int waveline,bool noPoison = false ) - { - switch( this.searchEnemyFunc) + /// <summary> + /// returns the radius of the collider whether + /// its a sphere or capsule + /// </summary> + public float effectRadius + { + get { - case EEnemySelFunc.Nearest: - case EEnemySelFunc.MaxHp: - case EEnemySelFunc.Random: - { - if (bOpponent) + var sphere = attachedCollider as SphereCollider; + if (sphere != null) + { + return sphere.radius; + } + var capsule = attachedCollider as CapsuleCollider; + if (capsule != null) + { + return capsule.radius; + } + return 0; + } + } + + /// <summary> + /// The alignment of the affector + /// </summary> + public IAlignmentProvider alignment; + + /// <summary> + /// Returns the current target + /// </summary> + public Targetable GetTarget(int waveline, bool noPoison = false) + { + switch (this.searchEnemyFunc) + { + case EEnemySelFunc.Nearest: + case EEnemySelFunc.MaxHp: + case EEnemySelFunc.Random: + { + if (bOpponent) { - //return AgentInsManager.instance.oppoMinDisAgent; - if (waveline >= 0) - return AgentInsManager.instance.GetMinDisAgent(waveline, true,false,noPoison); - else - { - Debug.Log("当前Opponent传入的参数waveLine is:" + waveline); - return AgentInsManager.instance.MinDisAgent; - } - } - else - { - //return AgentInsManager.instance.MinDisAgent; - if(waveline>= 0) - return AgentInsManager.instance.GetMinDisAgent(waveline,false,false, noPoison ); + //return AgentInsManager.instance.oppoMinDisAgent; + if (waveline >= 0) + return AgentInsManager.instance.GetMinDisAgent(waveline, true, false, noPoison); else { - Debug.Log("当前传入的参数waveLine is:" + waveline); - return AgentInsManager.instance.MinDisAgent; - } - - } - - } -/* case EEnemySelFunc.MaxHp: - { - return AgentInsManager.instance.getMaxHpAgent(bOpponent); - } - case EEnemySelFunc.Random: - { - return AgentInsManager.instance.getRandomAgent(bOpponent); - }*/ + Debug.Log("当前Opponent传入的参数waveLine is:" + waveline); + return AgentInsManager.instance.MinDisAgent; + } + } + else + { + //return AgentInsManager.instance.MinDisAgent; + if (waveline >= 0) + return AgentInsManager.instance.GetMinDisAgent(waveline, false, false, noPoison); + else + { + Debug.Log("当前传入的参数waveLine is:" + waveline); + return AgentInsManager.instance.MinDisAgent; + } + + } + + } + /* case EEnemySelFunc.MaxHp: + { + return AgentInsManager.instance.getMaxHpAgent(bOpponent); + } + case EEnemySelFunc.Random: + { + return AgentInsManager.instance.getRandomAgent(bOpponent); + }*/ } - return null; - } + return null; + } - /// <summary> - /// 是否是对手战斗方. - /// </summary> - public bool bOpponent { set; get; } + /// <summary> + /// 是否是对手战斗方. + /// </summary> + public bool bOpponent { set; get; } - /// <summary> - /// Clears the list of current targets and clears all events - /// </summary> - public void ResetTargetter() - { - m_TargetsInRange.Clear(); - m_CurrrentTargetable = null; + /// <summary> + /// Clears the list of current targets and clears all events + /// </summary> + public void ResetTargetter() + { + m_TargetsInRange.Clear(); + m_CurrrentTargetable = null; - targetEntersRange = null; - targetExitsRange = null; - acquiredTarget = null; - lostTarget = null; + targetEntersRange = null; + targetExitsRange = null; + acquiredTarget = null; + lostTarget = null; - // Reset turret facing - if (turret != null) - { - turret.localRotation = Quaternion.identity; - } - } - - /// <summary> - /// Returns all the targets within the collider. This list must not be changed as it is the working - /// list of the targetter. Changing it could break the targetter - /// </summary> - public List<Targetable> GetAllTargets() - { - switch( searchEnemyFunc) + // Reset turret facing + if (turret != null) { - case EEnemySelFunc.MaxHp: + turret.localRotation = Quaternion.identity; + } + } + + /// <summary> + /// Returns all the targets within the collider. This list must not be changed as it is the working + /// list of the targetter. Changing it could break the targetter + /// </summary> + public List<Targetable> GetAllTargets() + { + switch (searchEnemyFunc) + { + case EEnemySelFunc.MaxHp: { - return AgentInsManager.instance.getAgentListMaxHp(bOpponent); + return AgentInsManager.instance.getAgentListMaxHp(bOpponent); } - case EEnemySelFunc.Random: + case EEnemySelFunc.Random: { - return AgentInsManager.instance.getAgentListRandom(bOpponent); + return AgentInsManager.instance.getAgentListRandom(bOpponent); } } - // 最后返回的就是距离计算的模式: - if (this.bOpponent) - return AgentInsManager.instance.OppoAgentInRange; - else - return AgentInsManager.instance.AgentInRange; - } + // 最后返回的就是距离计算的模式: + if (this.bOpponent) + return AgentInsManager.instance.OppoAgentInRange; + else + return AgentInsManager.instance.AgentInRange; + } - /// <summary> - /// Checks if the targetable is a valid target - /// </summary> - /// <param name="targetable"></param> - /// <returns>true if targetable is vaild, false if not</returns> - protected virtual bool IsTargetableValid(Targetable targetable) - { - if (targetable == null) - { - return false; - } - - IAlignmentProvider targetAlignment = targetable.configuration.alignmentProvider; - bool canDamage = alignment == null || targetAlignment == null || - alignment.CanHarm(targetAlignment); - - return canDamage; - } + /// <summary> + /// Checks if the targetable is a valid target + /// </summary> + /// <param name="targetable"></param> + /// <returns>true if targetable is vaild, false if not</returns> + protected virtual bool IsTargetableValid(Targetable targetable) + { + if (targetable == null) + { + return false; + } - /// <summary> - /// On exiting the trigger, a valid targetable is removed from the tracking list. - /// </summary> - /// <param name="other">The other collider in the collision</param> - protected virtual void OnTriggerExit(Collider other) - { - var targetable = other.GetComponent<Targetable>(); - if (!IsTargetableValid(targetable)) - { - return; - } - - m_TargetsInRange.Remove(targetable); - if (targetExitsRange != null) - { - targetExitsRange(targetable); - } - if (targetable == m_CurrrentTargetable) - { - OnTargetRemoved(targetable); - } - else - { - // Only need to remove if we're not our actual target, otherwise OnTargetRemoved will do the work above - targetable.removed -= OnTargetRemoved; - } - } - - /// <summary> - /// On entering the trigger, a valid targetable is added to the tracking list. - /// </summary> - /// <param name="other">The other collider in the collision</param> - protected virtual void OnTriggerEnter(Collider other) - { - GameObject tobj = this.transform.parent.gameObject; - Collider tcol = GetComponent<Collider>(); + IAlignmentProvider targetAlignment = targetable.configuration.alignmentProvider; + bool canDamage = alignment == null || targetAlignment == null || + alignment.CanHarm(targetAlignment); - var targetable = other.GetComponent<Targetable>(); - if (!IsTargetableValid(targetable)) - { - return; - } - targetable.removed += OnTargetRemoved; - m_TargetsInRange.Add(targetable); - if (targetEntersRange != null) - { - targetEntersRange(targetable); - } - } + return canDamage; + } - /// <summary> - /// Returns the nearest targetable within the currently tracked targetables - /// </summary> - /// <returns>The nearest targetable if there is one, null otherwise</returns> - protected virtual Targetable GetNearestTargetable() - { + /// <summary> + /// On exiting the trigger, a valid targetable is removed from the tracking list. + /// </summary> + /// <param name="other">The other collider in the collision</param> + protected virtual void OnTriggerExit(Collider other) + { + var targetable = other.GetComponent<Targetable>(); + if (!IsTargetableValid(targetable)) + { + return; + } + + m_TargetsInRange.Remove(targetable); + if (targetExitsRange != null) + { + targetExitsRange(targetable); + } + if (targetable == m_CurrrentTargetable) + { + OnTargetRemoved(targetable); + } + else + { + // Only need to remove if we're not our actual target, otherwise OnTargetRemoved will do the work above + targetable.removed -= OnTargetRemoved; + } + } + + /// <summary> + /// On entering the trigger, a valid targetable is added to the tracking list. + /// </summary> + /// <param name="other">The other collider in the collision</param> + protected virtual void OnTriggerEnter(Collider other) + { + GameObject tobj = this.transform.parent.gameObject; + Collider tcol = GetComponent<Collider>(); + + var targetable = other.GetComponent<Targetable>(); + if (!IsTargetableValid(targetable)) + { + return; + } + targetable.removed += OnTargetRemoved; + m_TargetsInRange.Add(targetable); + if (targetEntersRange != null) + { + targetEntersRange(targetable); + } + } + + /// <summary> + /// Returns the nearest targetable within the currently tracked targetables + /// </summary> + /// <returns>The nearest targetable if there is one, null otherwise</returns> + protected virtual Targetable GetNearestTargetable() + { // 使用统一管理的管理器接口. if (this.bOpponent) return AgentInsManager.instance.oppoMinDisAgent; - else - return AgentInsManager.instance.MinDisAgent; - } + else + return AgentInsManager.instance.MinDisAgent; + } - /// <summary> - /// Starts the search timer - /// </summary> - protected virtual void Start() - { - m_SearchTimer = searchRate; - m_WaitTimer = idleWaitTime; + /// <summary> + /// Starts the search timer + /// </summary> + protected virtual void Start() + { + m_SearchTimer = searchRate; + m_WaitTimer = idleWaitTime; - } + } - /// <summary> - /// Checks if any targets are destroyed and aquires a new targetable if appropriate - /// </summary> - protected virtual void Update() - { - m_SearchTimer -= Time.deltaTime; + /// <summary> + /// Checks if any targets are destroyed and aquires a new targetable if appropriate + /// </summary> + protected virtual void Update() + { + m_SearchTimer -= Time.deltaTime; - if (m_SearchTimer <= 0.0f && m_CurrrentTargetable == null && m_TargetsInRange.Count > 0) - { - m_CurrrentTargetable = GetNearestTargetable(); - if (m_CurrrentTargetable != null) - { - if (acquiredTarget != null) - { - acquiredTarget(m_CurrrentTargetable); - } - m_SearchTimer = searchRate; - } - } + if (m_SearchTimer <= 0.0f && m_CurrrentTargetable == null && m_TargetsInRange.Count > 0) + { + m_CurrrentTargetable = GetNearestTargetable(); + if (m_CurrrentTargetable != null) + { + if (acquiredTarget != null) + { + acquiredTarget(m_CurrrentTargetable); + } + m_SearchTimer = searchRate; + } + } - AimTurret(); + AimTurret(); - m_HadTarget = m_CurrrentTargetable != null; - } + m_HadTarget = m_CurrrentTargetable != null; + } - /// <summary> - /// Fired by the agents died event or when the current target moves out of range, - /// Fires the lostTarget event. - /// </summary> - void OnTargetRemoved(DamageableBehaviour target) - { - target.removed -= OnTargetRemoved; - if (m_CurrrentTargetable != null && target.configuration == m_CurrrentTargetable.configuration) - { - if (lostTarget != null) - { - lostTarget(); - } - m_HadTarget = false; - m_TargetsInRange.Remove(m_CurrrentTargetable); - m_CurrrentTargetable = null; - m_XRotationCorrectionTime = 0.0f; - } - else //wasnt the current target, find and remove from targets list - { - for (int i = 0; i < m_TargetsInRange.Count; i++) - { - if (m_TargetsInRange[i].configuration == target.configuration) - { - m_TargetsInRange.RemoveAt(i); - break; - } - } - } - } + /// <summary> + /// Fired by the agents died event or when the current target moves out of range, + /// Fires the lostTarget event. + /// </summary> + void OnTargetRemoved(DamageableBehaviour target) + { + target.removed -= OnTargetRemoved; + if (m_CurrrentTargetable != null && target.configuration == m_CurrrentTargetable.configuration) + { + if (lostTarget != null) + { + lostTarget(); + } + m_HadTarget = false; + m_TargetsInRange.Remove(m_CurrrentTargetable); + m_CurrrentTargetable = null; + m_XRotationCorrectionTime = 0.0f; + } + else //wasnt the current target, find and remove from targets list + { + for (int i = 0; i < m_TargetsInRange.Count; i++) + { + if (m_TargetsInRange[i].configuration == target.configuration) + { + m_TargetsInRange.RemoveAt(i); + break; + } + } + } + } /// <summary> /// Aims the turret at the current target /// 将炮塔对准当前目标 /// </summary> protected virtual void AimTurret() - { - if (turret == null) - { - return; - } + { + if (turret == null) + { + return; + } - if (m_CurrrentTargetable == null) // do idle rotation - { - if (m_WaitTimer > 0) - { - m_WaitTimer -= Time.deltaTime; - if (m_WaitTimer <= 0) - { - m_CurrentRotationSpeed = (Random.value * 2 - 1) * idleRotationSpeed; - } - } - else - { - Vector3 euler = turret.rotation.eulerAngles; - euler.x = Mathf.Lerp(Wrap180(euler.x), 0, m_XRotationCorrectionTime); - m_XRotationCorrectionTime = Mathf.Clamp01((m_XRotationCorrectionTime + Time.deltaTime) / idleCorrectionTime); - euler.y += m_CurrentRotationSpeed * Time.deltaTime; + if (m_CurrrentTargetable == null) // do idle rotation + { + if (m_WaitTimer > 0) + { + m_WaitTimer -= Time.deltaTime; + if (m_WaitTimer <= 0) + { + m_CurrentRotationSpeed = (Random.value * 2 - 1) * idleRotationSpeed; + } + } + else + { + Vector3 euler = turret.rotation.eulerAngles; + euler.x = Mathf.Lerp(Wrap180(euler.x), 0, m_XRotationCorrectionTime); + m_XRotationCorrectionTime = Mathf.Clamp01((m_XRotationCorrectionTime + Time.deltaTime) / idleCorrectionTime); + euler.y += m_CurrentRotationSpeed * Time.deltaTime; - turret.eulerAngles = euler; - } - } - else - { - m_WaitTimer = idleWaitTime; + turret.eulerAngles = euler; + } + } + else + { + m_WaitTimer = idleWaitTime; - Vector3 targetPosition = m_CurrrentTargetable.position; - if (onlyYTurretRotation) - { - targetPosition.y = turret.position.y; - } - Vector3 direction = targetPosition - turret.position; - Quaternion look = Quaternion.LookRotation(direction, Vector3.up); - Vector3 lookEuler = look.eulerAngles; - // We need to convert the rotation to a -180/180 wrap so that we can clamp the angle with a min/max - float x = Wrap180(lookEuler.x); - lookEuler.x = Mathf.Clamp(x, turretXRotationRange.x, turretXRotationRange.y); - look.eulerAngles = lookEuler; - turret.rotation = look; - } - } + Vector3 targetPosition = m_CurrrentTargetable.position; + if (onlyYTurretRotation) + { + targetPosition.y = turret.position.y; + } + Vector3 direction = targetPosition - turret.position; + Quaternion look = Quaternion.LookRotation(direction, Vector3.up); + Vector3 lookEuler = look.eulerAngles; + // We need to convert the rotation to a -180/180 wrap so that we can clamp the angle with a min/max + float x = Wrap180(lookEuler.x); + lookEuler.x = Mathf.Clamp(x, turretXRotationRange.x, turretXRotationRange.y); + look.eulerAngles = lookEuler; + turret.rotation = look; + } + } - /// <summary> - /// A simply function to convert an angle to a -180/180 wrap - /// </summary> - static float Wrap180(float angle) - { - angle %= 360; - if (angle < -180) - { - angle += 360; - } - else if (angle > 180) - { - angle -= 360; - } - return angle; - } - } + /// <summary> + /// A simply function to convert an angle to a -180/180 wrap + /// </summary> + static float Wrap180(float angle) + { + angle %= 360; + if (angle < -180) + { + angle += 360; + } + else if (angle > 180) + { + angle -= 360; + } + return angle; + } + } } \ No newline at end of file -- Gitblit v1.9.1