Files
MedievalShopkeeper/Assets/Scripts/Interactable.cs

78 lines
2.5 KiB
C#
Raw Normal View History

2026-09-03 16:35:05 +01:00
using UnityEngine;
using UnityEngine.Events;
namespace MedievalShopkeeper
{
/// <summary>
/// Base class for interactable shop entities (shelves, stock boxes, NPCs, registers).
/// Can be added directly to objects with UnityEvents configured in the inspector,
/// or inherited by specialized components like ShelfController or CustomerNPC.
/// </summary>
[SelectionBase]
public class Interactable : MonoBehaviour, IInteractable
{
[Header("Interaction Settings")]
[Tooltip("Text shown to the player when hovering/targeting this object.")]
[SerializeField] private string prompt = "Interact";
[Tooltip("Max distance the player must be within to trigger interaction.")]
[SerializeField] private float interactionRange = 2f;
[Tooltip("Optional specific point where the player should stand. If unassigned, defaults to this transform.")]
[SerializeField] private Transform interactionPoint;
[Tooltip("Whether interaction is currently permitted.")]
[SerializeField] private bool isInteractable = true;
[Header("Events")]
public UnityEvent<PlayerController> onInteracted;
public UnityEvent<PlayerController> onHoverEnter;
public UnityEvent<PlayerController> onHoverExit;
public virtual string InteractionPrompt => prompt;
public virtual Transform InteractionTransform => interactionPoint != null ? interactionPoint : transform;
public virtual float InteractionDistance => interactionRange;
public virtual bool CanInteract(PlayerController player)
{
return isInteractable && enabled && gameObject.activeInHierarchy;
}
public virtual void Interact(PlayerController player)
{
if (!CanInteract(player)) return;
onInteracted?.Invoke(player);
}
public virtual void OnHoverEnter(PlayerController player)
{
onHoverEnter?.Invoke(player);
}
public virtual void OnHoverExit(PlayerController player)
{
onHoverExit?.Invoke(player);
}
public void SetInteractable(bool interactable)
{
isInteractable = interactable;
}
public void SetPrompt(string newPrompt)
{
prompt = newPrompt;
}
protected virtual void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Vector3 center = InteractionTransform.position;
Gizmos.DrawWireSphere(center, interactionRange);
}
}
}