262 lines
8.7 KiB
C#
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);
|
|
}
|
|
}
|