using System.Collections; using System.Collections.Generic; using UnityEngine; public class CursorController : MonoBehaviour { [SerializeField] private Texture2D _defaultCursor; [SerializeField] private Texture2D _pickCursor; [SerializeField] private Texture2D _placeCursor; [SerializeField] private Texture2D _chalkCursor; [SerializeField] private float _interactionDistance = 3f; [SerializeField] private Camera _camera; [SerializeField] private float _holdDistance = 1f; [SerializeField] private float _followSpeed = 12f; private GameObject _heldObject; private Rigidbody _heldRigidbody; private Collider _heldCollider; private ChalkDrawer _chalkDrawer; private void Start() { Cursor.lockState = CursorLockMode.Confined; Cursor.visible = true; SetCursor(_defaultCursor); _chalkDrawer = GetComponent(); } private void Update() { if (_chalkDrawer != null && _chalkDrawer.IsHoldingChalk) return; if (Input.GetMouseButtonDown(1)) { NoteBookController nb = FindOpenNotebook(); if (nb != null) { nb.CloseNotebook(); return; } } HandleRaycast(); HandleHeldObject(); ForceEnableColliders(); } private NoteBookController FindOpenNotebook() { GameObject[] notes = GameObject.FindGameObjectsWithTag("Note"); foreach (var n in notes) { NoteBookController nb = n.GetComponent(); if (nb != null && nb.IsOpen) return nb; } return null; } private void ForceEnableColliders() { if (_heldObject != null) return; GameObject[] targets = GameObject.FindGameObjectsWithTag("Target"); foreach (GameObject target in targets) { Collider col = target.GetComponent(); if (col == null) col = target.GetComponentInChildren(); if (col != null && !col.enabled) { col.enabled = true; Rigidbody rb = target.GetComponent(); if (rb != null) rb.WakeUp(); } } } private void HandleRaycast() { if (FindOpenNotebook() != null) return; Ray ray = _camera.ScreenPointToRay(Input.mousePosition); RaycastHit[] hits = Physics.SphereCastAll(ray, 0.25f, _interactionDistance); foreach (RaycastHit h in hits) { if (h.collider.CompareTag("Chalk")) { SetCursor(_chalkCursor); if (Input.GetMouseButtonDown(0) && _chalkDrawer != null) _chalkDrawer.PickupChalk(h.collider.gameObject); return; } if (h.collider.CompareTag("Towel")) { SetCursor(_chalkCursor); if (Input.GetMouseButtonDown(0) && _chalkDrawer != null) _chalkDrawer.PickupTowel(h.collider.gameObject); return; } if (h.collider.CompareTag("Note")) { SetCursor(_chalkCursor); if (Input.GetMouseButtonDown(0)) { NoteBookController nb = h.collider.GetComponent(); if (nb != null) nb.OpenNotebook(); } return; } } if (_heldObject != null) { if (Physics.Raycast(ray, out RaycastHit hit, _interactionDistance * 3f, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore)) { if (hit.collider.CompareTag("Shelf")) { SetCursor(_placeCursor); if (Input.GetMouseButtonDown(0)) { Transform place = hit.collider.transform.Find("Place"); if (place != null) { Collider placeCollider = place.GetComponent(); if (placeCollider != null) PlaceObject(placeCollider); } } return; } if (hit.collider.CompareTag("Scale")) { SetCursor(_placeCursor); if (Input.GetMouseButtonDown(0)) { Transform platform = hit.collider.transform.Find("platform"); if (platform != null) { Collider platformCollider = platform.GetComponent(); if (platformCollider != null) PlaceOnScale(platformCollider); } } return; } } SetCursor(_pickCursor); if (Input.GetMouseButtonDown(0)) DropObject(); return; } if (Physics.Raycast(ray, out RaycastHit hitTarget, _interactionDistance, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore)) { if (hitTarget.collider.CompareTag("Target")) { SetCursor(_pickCursor); if (Input.GetMouseButtonDown(0)) PickUpObject(hitTarget.collider.gameObject); return; } } SetCursor(_defaultCursor); } private void PlaceOnScale(Collider platformCollider) { if (_heldObject == null) return; Bounds b = platformCollider.bounds; Collider objCollider = _heldObject.GetComponent(); if (objCollider == null) objCollider = _heldObject.GetComponentInChildren(); float objectHeight = objCollider != null ? objCollider.bounds.extents.y : 0.1f; _heldObject.transform.position = new Vector3(b.center.x, b.max.y + objectHeight, b.center.z); if (_heldCollider != null) _heldCollider.enabled = true; if (_heldRigidbody != null) { _heldRigidbody.useGravity = true; _heldRigidbody.WakeUp(); } _heldObject = null; _heldRigidbody = null; _heldCollider = null; SetCursor(_defaultCursor); } private void HandleHeldObject() { if (_heldObject == null) return; Ray ray = _camera.ScreenPointToRay(Input.mousePosition); Vector3 targetPosition; if (Physics.Raycast(ray, out RaycastHit hit, _holdDistance)) targetPosition = hit.point - ray.direction * 0.15f; else targetPosition = ray.origin + ray.direction * _holdDistance; _heldObject.transform.position = Vector3.Lerp( _heldObject.transform.position, targetPosition, Time.deltaTime * _followSpeed ); } private void PickUpObject(GameObject obj) { _heldObject = obj; _heldRigidbody = obj.GetComponent(); _heldCollider = obj.GetComponent(); if (_heldCollider == null) _heldCollider = obj.GetComponentInChildren(); if (_heldRigidbody != null) { _heldRigidbody.WakeUp(); _heldRigidbody.useGravity = false; _heldRigidbody.velocity = Vector3.zero; _heldRigidbody.angularVelocity = Vector3.zero; } if (_heldCollider != null) _heldCollider.enabled = false; } private void PlaceObject(Collider placeCollider) { if (_heldObject == null) return; Bounds b = placeCollider.bounds; Collider objCollider = _heldObject.GetComponent(); if (objCollider == null) objCollider = _heldObject.GetComponentInChildren(); float objectHeight = objCollider != null ? objCollider.bounds.extents.y : 0.1f; _heldObject.transform.position = new Vector3(b.center.x, b.max.y + objectHeight, b.center.z); if (_heldCollider != null) _heldCollider.enabled = true; if (_heldRigidbody != null) { _heldRigidbody.useGravity = true; _heldRigidbody.WakeUp(); } _heldObject = null; _heldRigidbody = null; _heldCollider = null; SetCursor(_defaultCursor); } private void DropObject() { if (_heldCollider != null) _heldCollider.enabled = true; if (_heldRigidbody != null) { _heldRigidbody.useGravity = true; _heldRigidbody.WakeUp(); } _heldObject = null; _heldRigidbody = null; _heldCollider = null; SetCursor(_defaultCursor); } private void SetCursor(Texture2D cursor) { Cursor.SetCursor(cursor, new Vector2(16, 16), CursorMode.Auto); } }