using UnityEngine; namespace OnlyScove.Scripts { public class EnvironmentScanner : MonoBehaviour { [Header("Obstacle Detection")] [SerializeField] private Vector3 forwardRayOffset = new Vector3(0, 1.5f, 0); [SerializeField] float forwardRayLength = 1.5f; [SerializeField] LayerMask obstacleLayer; [SerializeField] float heightRayLength = 2.5f; [Header("Interaction Detection")] [SerializeField] private Vector3 interactionOffset = new Vector3(0, 1.5f, 0); [SerializeField] private float interactionRadius = 0.5f; public ObstacleHitInfo ObstacleCheck() { var hitData = new ObstacleHitInfo(); var forwardOrigin = transform.position + forwardRayOffset; hitData.forwardHitFound = Physics.Raycast(transform.position + forwardRayOffset, transform.forward, out hitData.forwardHit, forwardRayLength, obstacleLayer ); Debug.DrawRay(forwardOrigin, transform.forward * forwardRayLength, (hitData.forwardHitFound) ? Color.red : Color.green); if (hitData.forwardHitFound) { var heightOrigin = hitData.forwardHit.point + Vector3.up * heightRayLength; hitData.heightHitFound = Physics.Raycast(heightOrigin, Vector3.down, out hitData.heightHit, heightRayLength, obstacleLayer); Debug.DrawRay(heightOrigin, Vector3.down * heightRayLength, (hitData.heightHitFound) ? Color.red : Color.green); } return hitData; } public IInteractable ScanForInteractable(float range, LayerMask mask) { if (Camera.main == null) return null; Transform camTransform = Camera.main.transform; Vector3 origin = camTransform.position; Vector3 direction = camTransform.forward; // Vẽ tia debug trong cửa sổ Scene để bạn kiểm tra (Nhấn nút Gizmos trong Scene để thấy) Debug.DrawRay(origin, direction * range, Color.blue); if (Physics.Raycast(origin, direction, out RaycastHit hit, range, mask)) { if (hit.collider.TryGetComponent(out IInteractable interactable)) { Debug.DrawLine(origin, hit.point, Color.red); // Tia chuyển đỏ khi chạm vật tương tác return interactable; } } return null; } public Vector3 GetLastInteractionPoint(float range, LayerMask mask) { if (Camera.main == null) return Vector3.zero; Transform camTransform = Camera.main.transform; if (Physics.Raycast(camTransform.position, camTransform.forward, out RaycastHit hit, range, mask)) return hit.point; return Vector3.zero; } private void OnDrawGizmosSelected() { Gizmos.color = Color.cyan; Vector3 origin = transform.position + interactionOffset; Gizmos.DrawLine(origin, origin + transform.forward * 2f); Gizmos.DrawWireSphere(origin + transform.forward * 2f, interactionRadius); } } } public struct ObstacleHitInfo { public RaycastHit forwardHit; public RaycastHit heightHit; public bool forwardHitFound; public bool heightHitFound; }