Files
ScienceLab.FrictionForce/Assets/Scripts/CursorController.cs
2026-05-29 18:30:19 +03:00

262 lines
8.7 KiB
C#

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<ChalkDrawer>();
}
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<NoteBookController>();
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<Collider>();
if (col == null) col = target.GetComponentInChildren<Collider>();
if (col != null && !col.enabled)
{
col.enabled = true;
Rigidbody rb = target.GetComponent<Rigidbody>();
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<NoteBookController>();
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<Collider>();
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<Collider>();
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<Collider>();
if (objCollider == null)
objCollider = _heldObject.GetComponentInChildren<Collider>();
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<Rigidbody>();
_heldCollider = obj.GetComponent<Collider>();
if (_heldCollider == null) _heldCollider = obj.GetComponentInChildren<Collider>();
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<Collider>();
if (objCollider == null) objCollider = _heldObject.GetComponentInChildren<Collider>();
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);
}
}