Untitled

mail@pastecode.io avatar
unknown
plain_text
15 days ago
6.2 kB
3
Indexable
Never
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using Kaideu.Input;
using Kaideu.Utils;
using Kaideu.Interactables;
using System;

public class PlayerPOV : SingletonPattern<PlayerPOV>
{

    [SerializeField]
    Transform _handTransform;
    [SerializeField]
    Sprite _openHand;
    [SerializeField]
    Sprite _closedHand;
    [SerializeField]
    private LayerMask _holdables;
    [SerializeField]
    private LayerMask _interactables;
    [SerializeField]
    private LayerMask _slots;
    [SerializeField]
    private LayerMask _surface;
    [SerializeField]
    private Vector3 _holdOffset;
    [SerializeField]
    private float _placementRange = 1;


    private Camera _cam;
    private GameObject _heldObject;
    private GameObject _currentInteractableObj;
    private Image _hand;
    private I_Interactable _currentInteractable;
    private Plane plane = new(Vector3.up, 0);


    public Vector3 HandPosition => _hand.transform.position;

    Vector3 DebugPoint; 

    // Start is called before the first frame update
    void Start()
    {
        _cam = Camera.main;
        _hand = _handTransform.GetComponent<Image>();

    }

    private void OnEnable()
    {
        InputManager.Instance.Controls.Table.PrimaryClickHold.performed += OnClick;
        InputManager.Instance.Controls.Table.Interact.performed += OnInteract;
    }

    private void OnDisable()
    {
        InputManager.Instance.Controls.Table.PrimaryClickHold.performed -= OnClick;
        InputManager.Instance.Controls.Table.Interact.performed -= OnInteract;
    }

    // Update is called once per frame
    void Update()
    {
        MoveHand();

        Ray ray = _cam.ScreenPointToRay(InputManager.Instance.Controls.Table.PrimaryPointPosition.ReadValue<Vector2>());
        float distance;
        if (plane.Raycast(ray, out distance))
        {
            var newPos = ray.GetPoint(distance) + Vector3.up * .2f;
            if (_heldObject)
            {
                _heldObject.transform.position = newPos + _holdOffset;
            }
            else
            {
                CheckForInteractable(ray);
            }
        }
    }

    private void CheckForInteractable(Ray ray)
    {
        if (Physics.Raycast(ray, out var hit, 1000, _interactables))
        {
            if (hit.collider.gameObject != _currentInteractableObj)
            {
                _currentInteractableObj = hit.collider.gameObject;
                _currentInteractable = _currentInteractableObj.GetComponent<I_Interactable>();
                _currentInteractable.ToggleInteractPrompts(true);
            }
        }
        else if (_currentInteractableObj)
        {
            _currentInteractable.ToggleInteractPrompts(false);
            _currentInteractableObj = null;
            _currentInteractable = null;
        }
    }

    void MoveHand()
    {
        var extents = _hand.sprite.bounds.extents;

        var topRight = _cam.ViewportToScreenPoint(Vector3.one);
        var bottomLeft = _cam.ViewportToScreenPoint(Vector3.zero);
        var mPos = InputManager.Instance.Controls.Table.PrimaryPointPosition.ReadValue<Vector2>();
        mPos.x = Mathf.Clamp(mPos.x, bottomLeft.x + extents.x, topRight.x - extents.x);
        mPos.y = Mathf.Clamp(mPos.y, bottomLeft.y + extents.y, topRight.y - extents.y);
        _hand.transform.position = mPos;
    }

    void AttemptGrabObject(GameObject obj)
    {
        _heldObject = obj;
    }

    void ReleaseObject(Ray ray)
    {
        _heldObject.transform.position = _heldObject.transform.position - _holdOffset;
        if (Physics.Raycast(ray, out var hit, 1000, _surface))
        {
            DebugPoint = hit.point;
            var cols = Physics.OverlapSphere(hit.point, _placementRange, _slots);
            if (cols.Length > 0)
            {
                print(cols.Length);
                Collider closest = cols[0];
                foreach (var col in cols) 
                {
                    var temp = col.GetComponent<IngredientSlot>();

                    //print($"{temp.name} - {temp.GetType() == typeof(DedicatedIngredientSlot)} && {((DedicatedIngredientSlot)temp).CanPlace(_heldObject.GetComponent<Ingredient>().Type)}");

                    if (temp.GetType() == typeof(DedicatedIngredientSlot) && !(((DedicatedIngredientSlot)temp).CanPlace(_heldObject.GetComponent<Ingredient>().Type)))
                        continue;
                    else if (Vector3.Distance(col.ClosestPoint(hit.point), hit.point) < Vector3.Distance(closest.ClosestPoint(hit.point), hit.point))
                        closest = col;

                }

                closest.GetComponent<IngredientSlot>().TryPlace(_heldObject.GetComponent<Ingredient>());
            }
            /**/
        }
        _heldObject = null;
    }

    private void InteractWith(GameObject obj)
    {
        obj.GetComponent<I_Interactable>().TryInteract();
    }

    void OnClick(InputAction.CallbackContext ctx)
    {
        bool pressed = InputManager.Instance.Controls.Table.PrimaryClickHold.ReadValue<float>() > 0;
        var ray = _cam.ScreenPointToRay(InputManager.Instance.Controls.Table.PrimaryPointPosition.ReadValue<Vector2>());

        _hand.sprite = (pressed) ? _closedHand : _openHand;

        if (pressed)
        {
            if (Physics.Raycast(ray, out var hitDataH, 1000, _holdables))
            {
                AttemptGrabObject(hitDataH.collider.gameObject);

                if (Physics.Raycast(ray, out var hitDataS, 1000, _slots))
                    hitDataS.collider.GetComponent<IngredientSlot>().RemoveFrom();
            }
        }
        else if (_heldObject)
            ReleaseObject(ray);
    }

    private void OnInteract(InputAction.CallbackContext ctx)
    {
        if (_currentInteractableObj)
        {
            _currentInteractable.TryInteract();
        }
    }

#if UNITY_EDITOR
    private void OnDrawGizmos()
    {
        if (DebugPoint != Vector3.zero)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(DebugPoint, 1);
        }
    }
#endif
}
Leave a Comment