working on quest and interaction system
This commit is contained in:
100
Assets/Scripts/InteractionController.cs
Normal file
100
Assets/Scripts/InteractionController.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public class InteractionController : MonoBehaviour
|
||||
{
|
||||
[Header("Interaction Settings")]
|
||||
[Tooltip("How large the proximity bubble is around the player (e.g. 3 meters).")]
|
||||
public float interactionDistance = 3f;
|
||||
[Tooltip("Layers that contain interactable objects (e.g. NPC, Default)")]
|
||||
public LayerMask interactableLayers;
|
||||
|
||||
[Header("References")]
|
||||
public PlayerUIManager uiManager;
|
||||
|
||||
[Header("Input")]
|
||||
[Tooltip("The key used to interact")]
|
||||
public Key interactKey = Key.E;
|
||||
|
||||
// We store whatever we are currently closest to
|
||||
private IInteractable _currentInteractable;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (uiManager == null) return;
|
||||
|
||||
// Create a sphere around the player to find all interactables in range
|
||||
// Use QueryTriggerInteraction.Ignore so we don't accidentally interact with giant invisible AI/Aggro triggers!
|
||||
Collider[] hits = Physics.OverlapSphere(transform.position, interactionDistance, interactableLayers, QueryTriggerInteraction.Ignore);
|
||||
|
||||
IInteractable closestInteractable = null;
|
||||
float closestDistance = float.MaxValue;
|
||||
|
||||
// Loop through everything in our bubble to find the closest one
|
||||
foreach (var hit in hits)
|
||||
{
|
||||
// Ignore our own body
|
||||
if (hit.transform.root == transform.root) continue;
|
||||
|
||||
IInteractable interactable = hit.GetComponentInParent<IInteractable>();
|
||||
if (interactable != null && interactable.CanInteract())
|
||||
{
|
||||
float dist = Vector3.Distance(transform.position, hit.ClosestPoint(transform.position));
|
||||
|
||||
if (dist < closestDistance)
|
||||
{
|
||||
closestDistance = dist;
|
||||
closestInteractable = interactable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we found something valid nearby
|
||||
if (closestInteractable != null)
|
||||
{
|
||||
if (_currentInteractable != closestInteractable)
|
||||
{
|
||||
_currentInteractable = closestInteractable;
|
||||
ShowPrompt(closestInteractable.GetInteractText(), closestInteractable.GetSecondaryInteractText());
|
||||
}
|
||||
|
||||
// Listen for input
|
||||
if (Keyboard.current != null && Keyboard.current[interactKey].wasPressedThisFrame)
|
||||
{
|
||||
closestInteractable.Interact(gameObject);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing in range, or closest thing can't be interacted with anymore
|
||||
if (_currentInteractable != null)
|
||||
{
|
||||
_currentInteractable = null;
|
||||
HidePrompt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowPrompt(string actionText, string secondaryText)
|
||||
{
|
||||
if (uiManager.interactionPanel != null) uiManager.interactionPanel.SetActive(true);
|
||||
if (uiManager.interactionText != null) uiManager.interactionText.text = actionText;
|
||||
|
||||
if (uiManager.interactionSecondaryText != null)
|
||||
{
|
||||
uiManager.interactionSecondaryText.text = secondaryText;
|
||||
}
|
||||
}
|
||||
|
||||
private void HidePrompt()
|
||||
{
|
||||
if (uiManager.interactionPanel != null) uiManager.interactionPanel.SetActive(false);
|
||||
}
|
||||
|
||||
// Draws a helpful visual bubble in the Scene view so you can see your interaction range!
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = new Color(0f, 1f, 0f, 0.3f);
|
||||
Gizmos.DrawSphere(transform.position, interactionDistance);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user