/// <summary> /// 立即治疗效果; /// </summary> private void ImmedHeal(CombatUnitController unit, CombatUnitController attacker, SkillEffectData effect) { if (unit != null) { unit.OnHeal(attacker, (int)effect.Para1, effect.HitEffect); } }
/// <summary> /// 查找最近距离单位; /// </summary> public virtual CombatUnitController FindTargetInRadius_MinDistance(int layer, bool includeCantBeAttack = false) { float minDistance = -1; CombatUnitController selectedUnit = null; Collider[] colliders = Physics.OverlapSphere(transform.position, m_CurCombatUnit.Spring, layer); foreach (Collider c in colliders) { CombatUnitController unit = c.gameObject.GetComponent <CombatUnitController>(); if (unit == null || unit.IsDead) { continue; } if (!includeCantBeAttack && unit.CantbeAttack > 0) { continue; } float distance = Vector3.Distance(transform.position, unit.transform.position); if (minDistance < 0) { minDistance = distance; selectedUnit = unit; } else { if (distance < minDistance) { minDistance = distance; selectedUnit = unit; } } } return(selectedUnit); }
private void ExecuteEffect(SkillEffectData effect, CombatUnitController unit, CombatUnitController attacker) { switch ((SkillEffectTypes)effect.Type) { case SkillEffectTypes.ImmedDamage: ImmedDamage(unit, attacker, effect); break; case SkillEffectTypes.ImmedHeal: ImmedHeal(unit, attacker, effect); break; case SkillEffectTypes.AddBuff: AddBuff(unit, attacker, effect); break; case SkillEffectTypes.Sneer: Sneer(unit, attacker); break; case SkillEffectTypes.HitDown: HitDown(unit, attacker, effect); break; case SkillEffectTypes.HitOut: HitOut(unit, attacker, effect); break; default: break; } }
/// <summary> /// 击飞效果; /// </summary> private void HitOut(CombatUnitController unit, CombatUnitController attacker, SkillEffectData effect) { if (unit != null) { unit.OnHitOut(attacker, (float)effect.Para1, (float)effect.Para2); } }
/// <summary> /// 击中目标; /// </summary> public void HitTarget(GameObject target, int skillEffectIndex = -1) { if (m_SkillCaster == null || target == null) { return; } CombatUnitController attacker = m_SkillCaster.GetComponent <CombatUnitController>(); CombatUnitController unit = target.GetComponent <CombatUnitController>(); if (skillEffectIndex == -1) { for (int i = 0; i < EffectList.Count; i++) { SkillEffectData effect = EffectList[i]; ExecuteEffect(effect, unit, attacker); } } else { if (skillEffectIndex >= 0 && skillEffectIndex < EffectList.Count) { SkillEffectData effect = EffectList[skillEffectIndex]; ExecuteEffect(effect, unit, attacker); } } }
/// <summary> /// 讥讽效果; /// </summary> private void Sneer(CombatUnitController unit, CombatUnitController attacker) { if (unit != null) { unit.OnSneer(attacker); } }
// <summary> /// 击倒; /// </summary> public virtual void OnHitDown(CombatUnitController attacker, float dist, float time) { if (attacker == null || m_IsDead || m_Animator == null) { return; } if (m_Animator.speed == 0) { return; } AnimatorStateInfo stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); if (stateInfo.IsName("Base Layer.hitdown") || stateInfo.IsName("Base Layer.hitout") || stateInfo.IsName("Base Layer.downup")) { return; } if (time <= 0 || dist <= 0) { return; } //TODO m_Animator.SetTrigger("HitDown"); HitBack(attacker, dist, time); }
public CombatUnitController GetAttackTarget(List <CombatUnitController> enemies, Vector3 targetPosition) { if (null == m_CurrentTarget) { CombatUnitController attackTarget = enemies[0]; if (enemies.Count > 1) { for (int i = 1; i < enemies.Count; i++) { attackTarget = (enemies[i].transform.position - targetPosition).magnitude < (attackTarget.transform.position - targetPosition).magnitude ? enemies[i] : attackTarget; } } m_CurrentTarget = attackTarget; return(attackTarget); } else if (!m_CurrentTarget.gameObject.activeInHierarchy) { m_CurrentTarget = null; return(GetAttackTarget(enemies, targetPosition)); } else { return(m_CurrentTarget); } }
//-------------------Skill HitEffect Start--------------------------------- /// <summary> /// 击中目标受到伤害; /// </summary> public virtual void OnDamaged(CombatUnitController attacker, float hp, float burstRatio, float burstMul, List <int> hitEffects) { if (attacker == null || m_IsDead) { return; } if (CantbeAttack > 0) { return; } bool burst = false; if (CommonHelper.OnProbability(burstRatio)) { burst = true; hp = hp * burstMul; } Hp = Mathf.Max(0, Hp - (int)hp); if (Hp == 0) { OnDead(); } else if (Hp > 0) { OnHurt(hitEffects); if (m_Target == null) { m_Target = attacker; } } }
/// <summary> /// 立即伤害效果; /// </summary> private void ImmedDamage(CombatUnitController unit, CombatUnitController attacker, SkillEffectData effect) { if (unit != null) { unit.OnDamaged(attacker, effect.Para1, effect.Para2, effect.Para3, effect.HitEffect); } }
/// <summary> /// 添加Buff; /// </summary> private void AddBuff(CombatUnitController unit, CombatUnitController attacker, SkillEffectData effect) { if (unit != null) { unit.OnAddBuff(attacker, (int)effect.Para1); } }
/// <summary> /// 添加Buff; /// </summary> public void OnAddBuff(CombatUnitController attacker, int buffId) { if (attacker == null || m_IsDead) { return; } //todo }
public override void OnDamaged(CombatUnitController attacker, float hp, float burstRatio, float burstMul, List <int> hitEffects) { base.OnDamaged(attacker, hp, burstRatio, burstMul, hitEffects); if (!IsDead) { //TODO } }
/// <summary> /// 嘲讽; /// </summary> public virtual void OnSneer(CombatUnitController attacker) { if (attacker == null || m_IsDead) { return; } m_Target = attacker; }
void Update() { if (isWalking) { target = CombatController.Instance.FindClosestEnemyInRange(this, AgroRange); if (target != null) { isAttaking = true; } } }
public void AddUnitToTeam(CombatUnitController unit) { if (unit.team == Team.Red) { redTeamList.Add(unit); } else { blueTeamList.Add(unit); } }
private void Movement() { Vector3 targetPosition = m_TargetFinder.GetTargetPosition(m_Enemies, m_Allies, CombatManager.Instance.m_AttackRanges[(int)m_Type]); if (!m_AttackCoolingDown) { // check Target CombatUnitController newTarget = m_TargetFinder.GetAttackTarget(m_Enemies, targetPosition); if (newTarget != m_CurrentAttackTarget) { m_CurrentAttackTarget = newTarget; if (m_Type == CombatManager.UnitTypes.Assassin) { m_JumpToTarget = true; m_JumpTargetPosition = m_CurrentAttackTarget.transform.position + (m_CurrentAttackTarget.transform.position - transform.position).normalized * CombatManager.Instance.m_AttackRanges[(int)m_Type]; } } // check attack range if ((m_CurrentAttackTarget.transform.position - transform.position).magnitude > CombatManager.Instance.m_AttackRanges[(int)m_Type]) { m_MotorScript.MoveToPoint(m_CurrentAttackTarget.transform.position); } else { float targetCurrentHealth = m_CurrentAttackTarget.m_HealthScript.TakeDamage(CombatManager.Instance.m_AttackDamage[(int)m_Type]); if (targetCurrentHealth <= 0) { StartCoroutine(EliminateEnemy(m_CurrentAttackTarget)); CombatManager.Instance.UnitDefeated(m_CurrentAttackTarget, (int)m_CurrentAttackTarget.m_MyTeam); return; } Debug.Log($"{gameObject.name} attack {m_CurrentAttackTarget.name}"); m_IsAttacking = true; m_AttackCoolingDown = true; StartCoroutine(AttackCoolDown(2f)); } } else if (m_AttackCoolingDown) { if (CombatManager.UnitTypes.Assassin == m_Type) { if ((m_CurrentAttackTarget.transform.position - transform.position).magnitude > CombatManager.Instance.m_AttackRanges[(int)m_Type]) { m_MotorScript.MoveToPoint(m_CurrentAttackTarget.transform.position); } } m_MotorScript.MoveToPoint(targetPosition); } }
public CombatUnitController GetAttackTarget(List <CombatUnitController> enemies, Vector3 targetPosition) { CombatUnitController attackTarget = enemies[0]; if (enemies.Count > 1) { for (int i = 1; i < enemies.Count; i++) { attackTarget = (enemies[i].transform.position - targetPosition).magnitude < (attackTarget.transform.position - targetPosition).magnitude ? enemies[i] : attackTarget; } } return(attackTarget); }
/// <summary> /// 击退; /// </summary> void HitBack(CombatUnitController attacker, float dist, float time) { Vector3 backDist = transform.position - attacker.transform.position; if (backDist == Vector3.zero) { return; } backDist.Normalize(); Vector3 hitBackVel = backDist * dist; float hitBackAcc = -dist / time; StartCoroutine(HitingBack(hitBackVel, hitBackAcc)); }
/// <summary> /// 击中目标受到治疗; /// </summary> public virtual void OnHeal(CombatUnitController attacker, int hp, List <int> hitEffects) { if (attacker == null || m_IsDead) { return; } Hp = Mathf.Min(MaxHp, Hp + hp); for (int i = 0; i < hitEffects.Count; i++) { if (hitEffects[i] > 0) { EffectManager.Instance.CreateEffect(hitEffects[i], this.transform); } } }
public void UnitDefeated(CombatUnitController unit, int teamNum) { for (int i = 0; i < m_UnitPool[teamNum].Count; i++) { if (m_UnitPool[teamNum][i] == unit) { m_UnitPool[teamNum].RemoveAt(i); } } if (m_UnitPool[teamNum].Count < 1) { m_IsCombatCompleted = true; CombatComplete(teamNum); } }
/// <summary> /// 根据技能配置查找目标单位; /// </summary> protected void SelectTargetBySkill() { if (m_CurSelectedSkill == null) { return; } if (m_CurSelectedSkill.HitType == SkillHitTypes.ScaleEnemy || m_CurSelectedSkill.HitType == SkillHitTypes.SelectedEnemy) { if (m_Target != null) { if (m_Target.IsDead) { m_Target = null; } else { if (m_Target.CantbeAttack > 0) { m_Target = null; } if ((1 << m_Target.gameObject.layer) != EnemyLayer) { m_Target = null; } } } if (m_Target == null) { m_Target = FindTargetInRadius_MinDistance(EnemyLayer); } } else if (m_CurSelectedSkill.HitType == SkillHitTypes.ScaleFriend || m_CurSelectedSkill.HitType == SkillHitTypes.SelectedFriend) { m_Target = FindTargetInRadius_MinHp(FriendLayer, true); } else if (m_CurSelectedSkill.HitType == SkillHitTypes.Self) { m_Target = this; } }
/// <summary> /// 大招全部冻结; /// </summary> void OnAttackFreezedAll(float time) { int layerMask = 1 << LayerMask.NameToLayer("Warrior") | 1 << LayerMask.NameToLayer("AttackNpc"); Collider[] colliders = Physics.OverlapSphere(transform.position, 100, layerMask); foreach (Collider c in colliders) { CombatUnitController unit = c.gameObject.GetComponent <CombatUnitController>(); if (unit == null) { continue; } unit.Freezed(time); } }
/// <summary> /// 查询扇形范围目标; /// </summary> private void HitTargetsInFan(CombatUnitController attacker, int skillEffectIndex) { int count = 0; Vector3 dir = m_SkillCaster.transform.forward; Collider[] colliders = Physics.OverlapSphere(m_SkillCaster.transform.position, AttackRadius + 0.1f, TargetLayerMask); foreach (Collider c in colliders) { CombatUnitController unit = c.GetComponent <CombatUnitController>(); if (unit != null) { Vector3 testDir = c.transform.position - m_SkillCaster.transform.position; testDir.y = 0; if (testDir == Vector3.zero) { continue; } testDir.Normalize(); float dotProduct = Vector3.Dot(testDir, dir); if (dotProduct > 0) { float angleCos = Mathf.Cos(AttackAngle / 2.0f); if (dotProduct >= angleCos) { if (HitNum > -1) { if (count >= HitNum) { break; } } HitTarget(unit.gameObject, skillEffectIndex); count++; } } } } }
public void SkillHit(int skillEffectIndex) { if (m_SkillCaster == null) { return; } CombatUnitController attacker = m_SkillCaster.GetComponent <CombatUnitController>(); switch (HitType) { case SkillHitTypes.SelectedEnemy: case SkillHitTypes.SelectedFriend: case SkillHitTypes.Self: { HitTarget(m_SkillTarget, skillEffectIndex); } break; case SkillHitTypes.ScaleEnemy: case SkillHitTypes.ScaleFriend: { switch (HitSharpType) { case SkillHitSharpTypes.Circle: HitTargetsInCircle(attacker, skillEffectIndex); break; case SkillHitSharpTypes.Fan: HitTargetsInFan(attacker, skillEffectIndex); break; default: break; } } break; default: break; } }
public CombatUnitController FindClosestEnemyInRange(CombatUnitController unit, float range) { List <CombatUnitController> enemyList; enemyList = unit.team == Team.Red ? blueTeamList : redTeamList; float closestRange = Mathf.Infinity; float distance; CombatUnitController target = null; foreach (var enemy in enemyList) { distance = Vector3.Distance(enemy.transform.position, unit.transform.position); if (distance < range && distance < closestRange) { target = enemy; closestRange = distance; } } return(closestRange < range ? target : null); }
/// <summary> /// 查找随机单位; /// </summary> public virtual CombatUnitController FindTargetInRadius_Random(int layer, bool includeCantbeAttack = false) { Collider[] colliders = Physics.OverlapSphere(transform.position, CurCombatUnit.Spring, layer); List <object> allUnit = new List <object> (); foreach (Collider c in colliders) { CombatUnitController unit = c.gameObject.GetComponent <CombatUnitController>(); if (unit == null || unit.IsDead) { continue; } if (!includeCantbeAttack && unit.CantbeAttack > 0) { continue; } allUnit.Add(unit); } return(CommonHelper.RandomObject(allUnit) as CombatUnitController); }
/// <summary> /// 查找Hp最少单位; /// </summary> public virtual CombatUnitController FindTargetInRadius_MinHp(int layer, bool includeCantbeAttack = false) { float minHp = 0; CombatUnitController selectedUnit = null; Collider[] colliders = Physics.OverlapSphere(transform.position, m_CurCombatUnit.Spring, layer); foreach (Collider c in colliders) { CombatUnitController unit = c.gameObject.GetComponent <CombatUnitController>(); if (unit == null || unit.IsDead) { continue; } if (!includeCantbeAttack && unit.CantbeAttack > 0) { continue; } float hp = unit.HpRatio; if (minHp == 0) { minHp = hp; selectedUnit = unit; } else { if (hp < minHp) { minHp = hp; selectedUnit = unit; } } } if (selectedUnit.Hp >= selectedUnit.MaxHp) { selectedUnit = null; } return(selectedUnit); }
/// <summary> /// 查询圆形范围目标; /// </summary> private void HitTargetsInCircle(CombatUnitController attacker, int skillEffectIndex) { int count = 0; Collider[] colliders = Physics.OverlapSphere(m_SkillCaster.transform.position, AttackRadius + 0.1f, TargetLayerMask); foreach (Collider c in colliders) { CombatUnitController unit = c.GetComponent <CombatUnitController>(); if (unit != null) { if (HitNum > -1) { if (count >= HitNum) { break; } } HitTarget(unit.gameObject, skillEffectIndex); count++; } } }
private IEnumerator EliminateEnemy(CombatUnitController enemy) { yield return(null); enemy.gameObject.SetActive(false); }