using UnityEngine; public class PlayerHeadController : MonoBehaviour { [Header("Head")] public Transform Head; public Transform CameraTransform; public Transform BodyTransform; public float ThrowForce; public float PickupDistance; public bool isHoldingHead; [Header("Grabbable")] public Transform HandTransform; // in the future hand maybe grab items but for now its an empty object public float ItemThrowForce = 10f; public float ItemPickupDistance = 5f; private bool isHoldingItem; private Rigidbody m_itemRigidbody; private Collider m_itemCollider; private Transform m_currentItem; private Rigidbody m_headRigidbody; private Vector3 m_headInitialLocalPos; private Quaternion m_headInitialLocalRot; private Animator animator; private PlayerInputController input; private void Awake() { animator = GetComponent(); input = GetComponent(); } void Start() { Cursor.lockState = CursorLockMode.Locked; Vector3 offset = new Vector3(0f, -0.5f, 0.5f); m_headInitialLocalPos = BodyTransform.localPosition + offset; m_headInitialLocalRot = BodyTransform.localRotation; m_headRigidbody = Head.GetComponent(); Head.SetParent(null); } void Update() { if (input.HeadInteractionPressed) InteractHead(); if (input.ThrowPressed && isHoldingHead) ThrowHead(); if (input.InteractPressed) { if (!isHoldingItem) TryPickupItem(); else DropItem(); } if (input.ThrowPressed && isHoldingItem) ThrowItem(); } private void InteractHead() { if (!isHoldingHead) TryPickupHead(); else DropHead(); } private void TryPickupHead() { if (isHoldingHead || isHoldingItem) return; if (Vector3.Distance(transform.position, Head.position) <= PickupDistance) PickupHead(); } private void PickupHead() { isHoldingHead = true; if (m_headRigidbody != null) Destroy(m_headRigidbody); Head.SetParent(transform); Head.localPosition = m_headInitialLocalPos; Head.localRotation = m_headInitialLocalRot; } private void DropHead() { animator.SetTrigger("Throw"); isHoldingHead = false; Head.SetParent(null); m_headRigidbody = Head.gameObject.AddComponent(); m_headRigidbody.mass = 1f; m_headRigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezeRotationY; } private void ThrowHead() { DropHead(); m_headRigidbody.AddForce(CameraTransform.forward * ThrowForce, ForceMode.Impulse); } private void TryPickupItem() { if (isHoldingHead || isHoldingItem) return; int grabbableLayer = LayerMask.GetMask("Grabbable"); Collider[] hits = Physics.OverlapSphere(transform.position, ItemPickupDistance, grabbableLayer); foreach (Collider hit in hits) { m_currentItem = hit.transform; m_itemRigidbody = hit.GetComponent(); m_itemCollider = hit.GetComponent(); PickupItem(); return; } } private void PickupItem() { isHoldingItem = true; m_itemRigidbody.isKinematic = true; m_itemCollider.enabled = false; m_currentItem.SetParent(HandTransform); m_currentItem.localPosition = Vector3.zero; m_currentItem.localRotation = Quaternion.identity; } private void DropItem() { isHoldingItem = false; m_currentItem.SetParent(null); m_itemRigidbody.isKinematic = false; m_itemCollider.enabled = true; m_currentItem = null; } private void ThrowItem() { DropItem(); m_itemRigidbody.AddForce(BodyTransform.forward * ItemThrowForce, ForceMode.Impulse); } }