using UnityEngine; using System.Collections; using System.Collections.Generic; public class FirstPersonWeapon : MonoBehaviour { private Animator animator; public GameObject weaponVisual; public float animationDuration = 1.2f; public int damageAmount = 10; public GameObject damagePopupPrefab; public FirstPersonWeapon assignedWeapon; [Header("Attack Range Settings")] public float attackRange = 3f; // Maximum distance to hit public float attackAngle = 60f; // Cone angle in front of player (60 degrees = 30 each side) private void Start() { animator = GetComponent(); if (weaponVisual != null) weaponVisual.SetActive(false); } public void TriggerAttack() { if (animator == null || weaponVisual == null) return; StopAllCoroutines(); StartCoroutine(AttackRoutine()); } IEnumerator AttackRoutine() { weaponVisual.SetActive(true); animator.SetTrigger("Attack"); yield return new WaitForSeconds(0.2f); TryHitMonster(); yield return new WaitForSeconds(animationDuration - 0.2f); weaponVisual.SetActive(false); } void TryHitMonster() { GameObject player = GameObject.FindWithTag("Player"); if (player == null) return; Vector3 playerPos = player.transform.position; Vector3 playerForward = player.transform.forward; List validTargets = new List(); var monsterGroups = FindObjectsByType(FindObjectsSortMode.None); foreach (var group in monsterGroups) { var allMonsters = new List(); allMonsters.AddRange(group.frontRow); allMonsters.AddRange(group.backRow); foreach (var monster in allMonsters) { if (monster == null) continue; Vector3 monsterPos = monster.transform.position; float distance = Vector3.Distance(playerPos, monsterPos); if (distance <= attackRange) { Vector3 directionToMonster = (monsterPos - playerPos).normalized; float angle = Vector3.Angle(playerForward, directionToMonster); if (angle <= attackAngle / 2f) { validTargets.Add(monster); } } } } if (validTargets.Count > 0) { validTargets.Sort((a, b) => { float distA = Vector3.Distance(playerPos, a.transform.position); float distB = Vector3.Distance(playerPos, b.transform.position); return distA.CompareTo(distB); }); MonsterController target = validTargets[0]; target.TakeDamage(damageAmount); ShowDamagePopup(target.transform.position + Vector3.up * 2f, damageAmount); } } void ShowDamagePopup(Vector3 position, int amount) { if (damagePopupPrefab == null) return; GameObject popup = Instantiate(damagePopupPrefab, position, Quaternion.identity); var text = popup.GetComponentInChildren(); if (text != null) text.text = "-" + amount.ToString(); // Facultatif : orienter vers la caméra popup.transform.LookAt(Camera.main.transform); popup.transform.Rotate(0, 180, 0); // pour qu'il soit bien lisible } // Visualize attack range in editor private void OnDrawGizmosSelected() { GameObject player = GameObject.FindWithTag("Player"); if (player == null) return; Vector3 playerPos = player.transform.position; Vector3 playerForward = player.transform.forward; // Draw attack range sphere Gizmos.color = new Color(1f, 0f, 0f, 0.2f); Gizmos.DrawWireSphere(playerPos, attackRange); // Draw attack cone Gizmos.color = Color.red; Vector3 leftBoundary = Quaternion.Euler(0, -attackAngle / 2f, 0) * playerForward * attackRange; Vector3 rightBoundary = Quaternion.Euler(0, attackAngle / 2f, 0) * playerForward * attackRange; Gizmos.DrawLine(playerPos, playerPos + leftBoundary); Gizmos.DrawLine(playerPos, playerPos + rightBoundary); Gizmos.DrawLine(playerPos, playerPos + playerForward * attackRange); // Draw arc Vector3 previousPoint = playerPos + leftBoundary; for (int i = 1; i <= 20; i++) { float angle = Mathf.Lerp(-attackAngle / 2f, attackAngle / 2f, i / 20f); Vector3 direction = Quaternion.Euler(0, angle, 0) * playerForward; Vector3 point = playerPos + direction * attackRange; Gizmos.DrawLine(previousPoint, point); previousPoint = point; } } }