AttackTrigger.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using Base.Common;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using Sirenix.OdinInspector;
  6. using System;
  7. public class AttackTrigger : MonoBehaviour
  8. {
  9. [FoldoutGroup("场景交互-墙")] [LabelText("能破墙")] public bool canBreakWall;
  10. [FoldoutGroup("场景交互-墙")] public int wallBrealNum = 10;
  11. [FoldoutGroup("条件")] [LabelText("是否是远程角色")] public bool isShoot;
  12. [FoldoutGroup("条件")] [LabelText("是否为单体攻击")] public bool isSingleAttack;
  13. [FoldoutGroup("条件")] [LabelText("持续伤害")] public bool isDoT;
  14. public Character owner;
  15. public bool cantSingleAttack; //单体攻击单位是否已经攻击了
  16. [Header("攻击对象")]
  17. public List<BeHitTrigger> trigedObjs;
  18. public List<float> trigedTime;
  19. [Header("攻击属性")]
  20. public AttackController.AttackMethod attackMethod;
  21. public Vector3 force;
  22. public bool changeHurt;
  23. public float repelValue;
  24. public int offsetY = 1;
  25. public float hitRate = 1;
  26. [LabelText("伤害间隔时间")]public float interval;
  27. [Header("是否由士兵起手式创建")]
  28. public bool isCreatedByDemonicSummon = false;
  29. private void Awake()
  30. {
  31. owner = GetComponentInParent<Character>();
  32. }
  33. public virtual void Update()
  34. {
  35. DoT();
  36. }
  37. protected virtual void OnTriggerEnter(Collider other)
  38. {
  39. if (isShoot) return;
  40. if (!other.TryGetComponent(out BeHitTrigger hitTrigger)) return;
  41. Character hitOwner = hitTrigger.owner;
  42. if (hitOwner == null || hitOwner.isDie) return;
  43. if (isSingleAttack && cantSingleAttack) return;
  44. AttackController attackController = owner.attackController;
  45. if (!TryGetTargetTypeFromTag(hitOwner.tag, out TargetType otherTargetType)) return;
  46. if (!IsValidTargetType(attackController.targetTypes, otherTargetType)) return;
  47. trigedObjs.Add(hitTrigger);
  48. if (isDoT)
  49. {
  50. trigedTime.Add(0);
  51. return;
  52. }
  53. hitTrigger.BeHit(attackMethod, owner);
  54. if (hitTrigger.owner.debugAttackFrom)
  55. {
  56. hitTrigger.owner.DebugAttackFrom(owner.name, attackMethod.attackInfo.damage);
  57. }
  58. if (owner.TryGetComponent(out Demonic demonic))
  59. {
  60. hitTrigger.attackerID = demonic.id;
  61. }
  62. if (isSingleAttack)
  63. {
  64. cantSingleAttack = true;
  65. }
  66. }
  67. private HashSet<TargetType> _cachedTargetTypes;
  68. private List<TargetType> _lastTargetTypes;
  69. private bool IsValidTargetType(List<TargetType> targetTypes, TargetType checkType)
  70. {
  71. // 如果列表没有变化,使用缓存的HashSet
  72. if (targetTypes != _lastTargetTypes)
  73. {
  74. _cachedTargetTypes = new HashSet<TargetType>(targetTypes);
  75. _lastTargetTypes = targetTypes;
  76. }
  77. return _cachedTargetTypes.Contains(checkType);
  78. }
  79. private bool TryGetTargetTypeFromTag(string tag, out TargetType targetType)
  80. {
  81. return GameManager.TagToTargetTypeMap.TryGetValue(tag, out targetType);
  82. }
  83. private void OnTriggerExit(Collider other)
  84. {
  85. if (!isDoT) return;
  86. if (!other.TryGetComponent(out BeHitTrigger hitTrigger)) return;
  87. int index = trigedObjs.IndexOf(hitTrigger);
  88. if (index == -1) return;
  89. trigedObjs.Remove(hitTrigger);
  90. trigedTime.RemoveAt(index);
  91. }
  92. protected virtual void OnEnable()
  93. {
  94. trigedObjs.Clear();
  95. trigedTime.Clear();
  96. cantSingleAttack = false;
  97. if (isShoot)
  98. {
  99. CharacterColliders cc = GetComponentInParent<CharacterColliders>();
  100. switch (attackMethod.attackInfo.attackMethod_Type)
  101. {
  102. case AttackMethod_Type.Attack_Summon:
  103. cc.Attack_summonShootEvent(0);
  104. break;
  105. case AttackMethod_Type.Attack_March:
  106. cc.Attack_marchShootEvent(0);
  107. break;
  108. }
  109. }
  110. if (isCreatedByDemonicSummon) attackMethod.AddAdditionalEffects();
  111. }
  112. protected virtual void OnDisable()
  113. {
  114. if (canBreakWall)
  115. {
  116. canBreakWall = false;
  117. }
  118. if (isCreatedByDemonicSummon)
  119. {
  120. attackMethod.ClearAdditionalEffects();
  121. isCreatedByDemonicSummon = false;
  122. }
  123. }
  124. public void DoT()
  125. {
  126. if (!isDoT) return;
  127. for(int i = 0; i < trigedObjs.Count; i++)
  128. {
  129. BeHitTrigger beHitTrigger = trigedObjs[i];
  130. float time = trigedTime[i];
  131. if (beHitTrigger.owner.isDie)
  132. {
  133. continue;
  134. }
  135. time -= Time.deltaTime;
  136. if(time <= 0)
  137. {
  138. trigedTime[i] = interval;
  139. beHitTrigger.BeHit(attackMethod, owner);
  140. }
  141. else
  142. {
  143. trigedTime[i] = time;
  144. }
  145. }
  146. }
  147. }