FirstPersonWeapon.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public class FirstPersonWeapon : MonoBehaviour
  5. {
  6. private Animator animator;
  7. public GameObject weaponVisual;
  8. public float animationDuration = 1.2f;
  9. public int damageAmount = 10;
  10. public GameObject damagePopupPrefab;
  11. public FirstPersonWeapon assignedWeapon;
  12. [Header("Attack Range Settings")]
  13. public float attackRange = 3f; // Maximum distance to hit
  14. public float attackAngle = 60f; // Cone angle in front of player (60 degrees = 30 each side)
  15. private void Start()
  16. {
  17. animator = GetComponent<Animator>();
  18. if (weaponVisual != null)
  19. weaponVisual.SetActive(false);
  20. }
  21. public void TriggerAttack()
  22. {
  23. if (animator == null || weaponVisual == null) return;
  24. StopAllCoroutines();
  25. StartCoroutine(AttackRoutine());
  26. }
  27. IEnumerator AttackRoutine()
  28. {
  29. weaponVisual.SetActive(true);
  30. animator.SetTrigger("Attack");
  31. yield return new WaitForSeconds(0.2f);
  32. TryHitMonster();
  33. yield return new WaitForSeconds(animationDuration - 0.2f);
  34. weaponVisual.SetActive(false);
  35. }
  36. void TryHitMonster()
  37. {
  38. GameObject player = GameObject.FindWithTag("Player");
  39. if (player == null) return;
  40. Vector3 playerPos = player.transform.position;
  41. Vector3 playerForward = player.transform.forward;
  42. List<MonsterController> validTargets = new List<MonsterController>();
  43. var monsterGroups = FindObjectsByType<MonsterFormationGroup>(FindObjectsSortMode.None);
  44. foreach (var group in monsterGroups)
  45. {
  46. var allMonsters = new List<MonsterController>();
  47. allMonsters.AddRange(group.frontRow);
  48. allMonsters.AddRange(group.backRow);
  49. foreach (var monster in allMonsters)
  50. {
  51. if (monster == null) continue;
  52. Vector3 monsterPos = monster.transform.position;
  53. float distance = Vector3.Distance(playerPos, monsterPos);
  54. if (distance <= attackRange)
  55. {
  56. Vector3 directionToMonster = (monsterPos - playerPos).normalized;
  57. float angle = Vector3.Angle(playerForward, directionToMonster);
  58. if (angle <= attackAngle / 2f)
  59. {
  60. validTargets.Add(monster);
  61. }
  62. }
  63. }
  64. }
  65. if (validTargets.Count > 0)
  66. {
  67. validTargets.Sort((a, b) =>
  68. {
  69. float distA = Vector3.Distance(playerPos, a.transform.position);
  70. float distB = Vector3.Distance(playerPos, b.transform.position);
  71. return distA.CompareTo(distB);
  72. });
  73. MonsterController target = validTargets[0];
  74. target.TakeDamage(damageAmount);
  75. ShowDamagePopup(target.transform.position + Vector3.up * 2f, damageAmount);
  76. }
  77. }
  78. void ShowDamagePopup(Vector3 position, int amount)
  79. {
  80. if (damagePopupPrefab == null) return;
  81. GameObject popup = Instantiate(damagePopupPrefab, position, Quaternion.identity);
  82. var text = popup.GetComponentInChildren<TMPro.TextMeshPro>();
  83. if (text != null)
  84. text.text = "-" + amount.ToString();
  85. // Facultatif : orienter vers la caméra
  86. popup.transform.LookAt(Camera.main.transform);
  87. popup.transform.Rotate(0, 180, 0); // pour qu'il soit bien lisible
  88. }
  89. // Visualize attack range in editor
  90. private void OnDrawGizmosSelected()
  91. {
  92. GameObject player = GameObject.FindWithTag("Player");
  93. if (player == null) return;
  94. Vector3 playerPos = player.transform.position;
  95. Vector3 playerForward = player.transform.forward;
  96. // Draw attack range sphere
  97. Gizmos.color = new Color(1f, 0f, 0f, 0.2f);
  98. Gizmos.DrawWireSphere(playerPos, attackRange);
  99. // Draw attack cone
  100. Gizmos.color = Color.red;
  101. Vector3 leftBoundary = Quaternion.Euler(0, -attackAngle / 2f, 0) * playerForward * attackRange;
  102. Vector3 rightBoundary = Quaternion.Euler(0, attackAngle / 2f, 0) * playerForward * attackRange;
  103. Gizmos.DrawLine(playerPos, playerPos + leftBoundary);
  104. Gizmos.DrawLine(playerPos, playerPos + rightBoundary);
  105. Gizmos.DrawLine(playerPos, playerPos + playerForward * attackRange);
  106. // Draw arc
  107. Vector3 previousPoint = playerPos + leftBoundary;
  108. for (int i = 1; i <= 20; i++)
  109. {
  110. float angle = Mathf.Lerp(-attackAngle / 2f, attackAngle / 2f, i / 20f);
  111. Vector3 direction = Quaternion.Euler(0, angle, 0) * playerForward;
  112. Vector3 point = playerPos + direction * attackRange;
  113. Gizmos.DrawLine(previousPoint, point);
  114. previousPoint = point;
  115. }
  116. }
  117. }