using UnityEngine; using System.Collections; using System.Collections.Generic; public class GridMovement : MonoBehaviour { public float moveDistance = 1f; public float moveSpeed = 5f; public float rotationSpeed = 300f; public LayerMask moveZoneLayer; public ZoneManager zoneManager; public LayerMask groundLayer; public float groundRayDistance = 5f; public float playerHeightOffset = 0.8f; public LayerMask obstacleLayer; public float wallCheckDistance = 1f; public int currentFloorLevel = 0; private bool isMoving = false; private Vector2Int lastGridPosition; void Update() { if (isMoving) return; if (Input.GetKeyDown(KeyCode.W)) TryMove(transform.forward); if (Input.GetKeyDown(KeyCode.S)) TryMove(-transform.forward); if (Input.GetKeyDown(KeyCode.Q)) TryMove(-transform.right); if (Input.GetKeyDown(KeyCode.E)) TryMove(transform.right); if (Input.GetKeyDown(KeyCode.A)) StartCoroutine(Rotate(-90)); if (Input.GetKeyDown(KeyCode.D)) StartCoroutine(Rotate(90)); } void TryMove(Vector3 direction) { Vector3 origin = transform.position + Vector3.up * 0.5f; if (Physics.Raycast(origin, direction, wallCheckDistance, obstacleLayer)) { return; } Vector3 targetPos = transform.position + direction * moveDistance; if (zoneManager.IsPositionAllowed(targetPos)) { float groundY = GetGroundHeight(targetPos); if (groundY != Mathf.NegativeInfinity) { targetPos.y = groundY + playerHeightOffset; Sol sol = GetSolAtPosition(targetPos); if (sol != null) { currentFloorLevel = sol.floorLevel; } StartCoroutine(Move(targetPos)); } } } Sol GetSolAtPosition(Vector3 position) { Ray ray = new Ray(position + Vector3.up * groundRayDistance, Vector3.down); if (Physics.Raycast(ray, out RaycastHit hit, groundRayDistance * 2f, groundLayer)) { return hit.collider.GetComponent(); } return null; } float GetGroundHeight(Vector3 position) { Ray ray = new Ray(position + Vector3.up * groundRayDistance, Vector3.down); RaycastHit[] hits = Physics.RaycastAll(ray, groundRayDistance * 2f, groundLayer); foreach (RaycastHit hit in hits) { Sol sol = hit.collider.GetComponent(); if (sol != null && sol.floorLevel == currentFloorLevel) { return hit.point.y; } } // Aucun sol avec floorLevel trouvé : fallback if (Physics.Raycast(ray, out RaycastHit fallbackHit, groundRayDistance * 2f, groundLayer)) { return fallbackHit.point.y; } return Mathf.NegativeInfinity; } IEnumerator Move(Vector3 targetPos) { isMoving = true; Vector3 startPos = transform.position; float t = 0; while (t < 1) { t += Time.deltaTime * moveSpeed; transform.position = Vector3.Lerp(startPos, targetPos, t); yield return null; } transform.position = targetPos; isMoving = false; Vector2Int newGridPosition = new Vector2Int(Mathf.RoundToInt(transform.position.x), Mathf.RoundToInt(transform.position.z)); if (newGridPosition != lastGridPosition) { lastGridPosition = newGridPosition; // Fermer le panneau de recrutement si ouvert if (RecruitDialogueUI.Instance != null) RecruitDialogueUI.Instance.Hide(); } } IEnumerator Rotate(float angle) { isMoving = true; Quaternion startRot = transform.rotation; Quaternion endRot = startRot * Quaternion.Euler(0, angle, 0); float t = 0; while (t < 1) { t += Time.deltaTime * (rotationSpeed / 100); transform.rotation = Quaternion.Slerp(startRot, endRot, t); yield return null; } transform.rotation = endRot; isMoving = false; } public void MoveForward() => TryMove(transform.forward); public void MoveBackward() => TryMove(-transform.forward); public void StrafeLeft() => TryMove(-transform.right); public void StrafeRight() => TryMove(transform.right); public void TurnLeft() => StartCoroutine(Rotate(-90)); public void TurnRight() => StartCoroutine(Rotate(90)); }