Player Interactable RayCaster
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[System.Serializable]
public class PlayerInteractable_Raycaster_Comp : PlayerComponent
{
[Range(0, 100f)]
public float raycastRange = 100f;
private PlayerController _controller;
private PlayerCamera _playerCamera;
public IInteractable interactableCurrentTarget;
public IInteractable CurrentInteractable => interactableCurrentTarget;
public IInteractable lastInteractableTarget;
public IInteractable LastInteractable => lastInteractableTarget;
public InteractableEvent OnInteractable;
// Start is called before the first frame update
public override void Start()
{
_controller = transform.GetComponent<PlayerController>();
base.Start();
}
// Update is called once per frame
void Update()
{
CheckForInteractables();
}
public void Reset()
{
interactableCurrentTarget = null;
lastInteractableTarget = null;
}
void CheckForInteractables()
{
//Create a ray in the world using the middle of the viewport as the start point
Vector3 rayOrigin = _controller.PlayerCamera.cameraComp.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0));
int allLayersButPlayer = ~LayerMask.GetMask("Player");
if (Physics.Raycast(rayOrigin, _controller.PlayerCamera.cameraComp.transform.forward, out RaycastHit hitInfo, raycastRange, allLayersButPlayer))
{
interactableCurrentTarget = hitInfo.collider.gameObject.GetComponent<IInteractable>();
float distanceFromInteractable = Vector3.Distance(transform.position, hitInfo.collider.transform.position);
//Check the hitwidget interface exists
if (interactableCurrentTarget != null)
{
interactableCurrentTarget.OnTargetted();
//if the last interactable is not equal to the current one, that means this is a new one
if (interactableCurrentTarget != lastInteractableTarget)
{
if (lastInteractableTarget != null && lastInteractableTarget.Transform.gameObject != null)
{
lastInteractableTarget.OnTargetDropped();
}
//set this new widget as the last used
lastInteractableTarget = interactableCurrentTarget;
}
//else if it is the same widget as last time
else if (interactableCurrentTarget == lastInteractableTarget)
{
//do nothing for now
}
//If the distance between the player and interactable is less than the widgets interaction distance
if (distanceFromInteractable < interactableCurrentTarget.InteractionDistance)
{
OnInteractable.Invoke(interactableCurrentTarget);
}
}
//Else If ray hits nothing
else
{
////Check the last interactable isnt null
if (lastInteractableTarget != null)
{
if (lastInteractableTarget.gameObject != null)
{
//if it isnt call on target dropped
lastInteractableTarget.OnTargetDropped();
lastInteractableTarget = null;
}
}
}
}
}
}