using UnityEngine;
///
/// Interactable represents the base class of all interactable objects in the scene
///
public abstract class Interactable : MonoBehaviour
{
///
/// InteractinType is the type of an interaction. So the "PlayerInteractin.cs" can handle the interaction input.
///
///
/// - Click: A single click which triggers the Interact Method
/// - Hold: Holding a until time is reached an then triggers the Interact Method(Time resets if the Player stops holding)
/// - Harvest: Same as Hold but time does not reset. So the time progress gets saved. Used for class "Harvastable.cs"
///
///
public enum InteractionType {
Click,
Hold,
Harvest
}
[Header("Interactable Properties")]
public InteractionType interactionType;
[Tooltip("The time the player has to hold until the Interact method triggers.")]
[Range(0.1f, 99.9f)]
[SerializeField]
float holdDuration = 1f; // The time the player has to hold until the Interact method triggers
float holdTime; // The time for how long the player has already pressed
// Used to measure the distance between the player and the object
Transform playerTransform;
[Tooltip("The range in which the player can interact with an object")]
[Range(1f, 50f)]
[SerializeField]
float radius = 3f;
[SerializeField]
Transform centerPoint;
void Awake()
{
if(centerPoint == null)
{
centerPoint = gameObject.transform;
}
}
#region GETTER
///
/// GetDescription gets the description of an interactable object.
///
/// - The description is usally used to display a help text for the player (e.g. "Turn Lights On")
///
///
/// A string containing the description of the interactable object
public abstract string GetDescription();
///
/// GetHoldTime gets the time for how long the player has already pressed.
///
/// A float of the time for how long the player has already pressed
public float GetHoldTime() => holdTime;
///
/// GetHoldDuration gets the time the player has to hold until the Interact method triggers.
///
/// A float of the time the player has to hold until the Interact method triggers
public float GetHoldDuration() => holdDuration;
///
/// GetHoldTimeLeft gets the time for how long a player still has to hold.
///
/// A float containig the result of holdDuration - holdTime
public float GetHoldTimeLeft() => holdDuration - holdTime;
///
/// GetRadius gets the maximum distance of a player is allowed to have in order to interact with an object.
///
/// A float containing the interaction distance
public float GetRadius() => radius;
#endregion
///
/// Interact is the method which gets called when a player start the interaction with an object.
///
///
/// - If the player clicks on an object
/// - If the holdTime is greater or equals the holdDuration
/// - If the harvestTime is greater or equals the harvestDuration
///
///
/// It usually gets called in the "PlayerInteraction.cs"
///
public abstract void Interact();
///
/// IncreaseHoldTime increases the holdTime by Time.deltaTime.
/// holdTime += Time.deltaTime;
///
public void IncreaseHoldTime() => holdTime += Time.deltaTime;
///
/// ResetHoldTime resets the holdTime to 0f.
///
public void ResetHoldTime() => holdTime = 0f;
///
/// isInRange checks if the player is in the interaction range of an interactable object.
///
///
/// - True: Player is in range
/// - False: Player is NOT in range
///
///
/// A bool which says if the player is in the interaction range of an interactable object
public bool isInRange()
{
playerTransform = GameObject.FindGameObjectWithTag("Player").gameObject.transform; // Maybe singleton later?
float distance = Vector2.Distance(centerPoint.position, playerTransform.position);
if(distance <= radius)
{
return true;
}
else
{
return false;
}
}
// Show interactable range in editor but NOT IN-GAME
private void OnDrawGizmosSelected()
{
// Same as in "Awake()", cause the object does not get "awakend" in inspector
if (centerPoint == null)
{
centerPoint = gameObject.transform;
}
// Gizmos are only visible in the scene view -> NOT visible IN-GAME (DEBUG Reasons)
Gizmos.color = Color.magenta;
Gizmos.DrawWireSphere(centerPoint.position, radius);
}
}