Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Chronicles.Data.Mapping;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Events;
- [RequireComponent(typeof(Collider2D))]
- public class InteractableObject : MonoBehaviour {
- #region Inspector Fields
- [Header("Interactable Object Settings")]
- /// <summary>
- /// If set to <code>true</code>, only the player is able to interact
- /// </summary>
- [SerializeField]
- [Tooltip("If set, only the player is able to interact")]
- private bool requiresPlayer = true;
- /// <summary>
- /// The name of a tag that is required in order to interact
- /// </summary>
- [SerializeField]
- [Tooltip("(optional) The name of a tag that is required in order to interact (Leave empty if no tag is required!)")]
- private string requiresTag = "";
- /// <summary>
- /// The type of interaction that is required in order to trigger the interaction
- /// </summary>
- [SerializeField]
- [Tooltip("The type of interaction that is required in order to trigger the interaction")]
- private InteractionType interactionType;
- /// <summary>
- /// If set to <code>true</code> with this Interactable Object only one interaction is possible
- /// </summary>
- [SerializeField]
- [Tooltip("Set this flag to allow this Interactable Object to be interacted with only one time")]
- private bool oneTimeInteraction = false;
- /// <summary>
- /// If you need more than one but not infinite interactions you can set this value to your needs
- /// </summary>
- [SerializeField]
- [Tooltip("If you need more than one but not infinite interactions you can set this value to your needs")]
- private int maxInteractionCount = 0;
- /// <summary>
- /// The GameObject this InteractableObject component is attached to will be destroyed after interaction
- /// </summary>
- [Header("Interaction Behaviour")]
- [SerializeField]
- [Tooltip("The GameObject this InteractableObject component is attached to will be destroyed after interaction")]
- private bool destroyAfterInteraction = false;
- /// <summary>
- /// If Destroy After Interaction is enabled this amount of seconds will be used as delay before destroying the parent GameObject
- /// </summary>
- [SerializeField]
- [Tooltip("If Destroy After Interaction is enabled this amount of seconds will be used as delay before destroying the parent GameObject")]
- private float destroyDelay = 0.0f;
- #endregion Inspector Fields
- #region Public Unity Events
- [Header("Events")]
- [SerializeField]
- [Tooltip("Will be invoked on Interaction")]
- private UnityEvent onInteraction;
- #endregion Public Unity Events
- #region Public Properties
- /// <summary>
- /// Will be <code>true</code> if with this Interactable Object was interacted at least one time
- /// </summary>
- public bool Interacted
- {
- get
- {
- return InteractionCount > 0;
- }
- }
- /// <summary>
- /// The amount of interactions done on this InteractableObject
- /// </summary>
- public int InteractionCount
- {
- get;
- private set;
- }
- /// <summary>
- /// Will return the OneTimeInteraction flag
- /// </summary>
- public bool OneTimeInteraction
- {
- get
- {
- return this.oneTimeInteraction;
- }
- }
- #endregion Public Properties
- #region Public Fields
- /// <summary>
- /// The InteractionSheet contains detail informations about what will happen on interaction
- /// </summary>
- [HideInInspector]
- public InteractionSheet interactionSheet;
- #endregion
- #region MonoBehaviour Overrides
- private void OnValidate()
- {
- if (this.oneTimeInteraction)
- {
- this.maxInteractionCount = 1;
- }
- if (this.maxInteractionCount != 1)
- {
- this.oneTimeInteraction = false;
- }
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- // Ignore, if InteractionType is not Trigger
- if (this.interactionType != InteractionType.Trigger) return;
- InternalInteract(collision.transform);
- }
- #endregion MonoBehaviour Overrides
- #region Public Methods
- /// <summary>
- /// Invokes the interaction with the InteractableObject
- /// </summary>
- /// <param name="interactor">The interacting object</param>
- public void Interact(Transform interactor)
- {
- if (this.interactionType == InteractionType.Trigger) return;
- this.InternalInteract(interactor);
- }
- public bool CanInteract(Transform interactor)
- {
- // No Interactor -> false
- if (!interactor)
- {
- return false;
- }
- // Tag is required but not matching
- else if (string.IsNullOrWhiteSpace(requiresTag) == false && (interactor.tag.ToLower().Trim() != requiresTag.ToLower().Trim()))
- {
- return false;
- }
- // Player is required but not interacting
- else if (this.requiresPlayer && !Utils.IsPlayer(interactor.gameObject))
- {
- return false;
- }
- // OTI is enabled and interaction already happened
- else if (this.oneTimeInteraction && Interacted)
- {
- return false;
- }
- // Max Interaction Count is > 0 and the maximum was reached
- else if (this.maxInteractionCount > 0 && InteractionCount >= this.maxInteractionCount)
- {
- return false;
- }
- // If none of the conditions above are matching, interaction is possible
- else
- {
- return true;
- }
- }
- #endregion
- #region Private Methods
- /// <summary>
- /// Executes the interaction independent from the source
- /// </summary>
- /// <param name="interactor">The interacting object</param>
- private void InternalInteract(Transform interactor)
- {
- // Cancel interaction if interaction is not possible
- if (CanInteract(interactor) == false)
- {
- return;
- }
- // Debug info
- Debug.Log(interactor.name + " started interaction with " + gameObject.name);
- // Increase interaction count
- InteractionCount++;
- // Invoke UnityEvent event
- if (onInteraction != null)
- {
- onInteraction.Invoke();
- }
- // Interaction!
- this.ApplyInteractionSheet(interactor);
- // Destroy object after Interaction
- if (destroyAfterInteraction)
- {
- Destroy(gameObject, destroyDelay);
- }
- }
- /// <summary>
- /// Applies the attached InteractionSheet
- /// </summary>
- /// <param name="interactor"></param>
- private void ApplyInteractionSheet(Transform interactor)
- {
- if (!interactionSheet)
- {
- Debug.LogWarning("No Interaction Sheet attached!");
- return;
- }
- LivingEntity interactorEntity = interactor.GetComponent<LivingEntity>();
- InventoryController interactorInventory = interactor.GetComponent<InventoryController>();
- PlayerJournalController journalController = interactor.GetComponent<PlayerJournalController>();
- // Add / Remove Items
- if (interactionSheet.enableItemAdding)
- {
- if (interactorInventory)
- {
- interactorInventory.AddItemByID(interactionSheet.itemToBeAdded, interactionSheet.itemToBeAddedAmount);
- } else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no Inventory component");
- }
- }
- if (interactionSheet.enableItemRemoval && interactorInventory)
- {
- if (interactorInventory)
- {
- interactorInventory.RemoveItemsByID(interactionSheet.itemToBeRemoved, interactionSheet.itemToBeRemovedAmount);
- }
- else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no Inventory component");
- }
- }
- // Restore / Drain Health
- if (interactionSheet.enableHealthRestore && interactorEntity)
- {
- if (interactorEntity)
- {
- interactorEntity.RestoreHealth(interactionSheet.healthToRestore);
- }
- else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
- }
- }
- if (interactionSheet.enableHealthDrain && interactorEntity)
- {
- if (interactorEntity)
- {
- interactorEntity.DrainHealth(interactionSheet.healthToDrain);
- }
- else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
- }
- }
- // Restore / Drain Stamina
- if (interactionSheet.enableStaminaRestore && interactorEntity)
- {
- if (interactorEntity)
- {
- interactorEntity.RestoreStamina(interactionSheet.staminaToRestore);
- }
- else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
- }
- }
- if (interactionSheet.enableStaminaDrain && interactorEntity)
- {
- if (interactorEntity)
- {
- interactorEntity.DrainStamina(interactionSheet.staminaToDrain);
- }
- else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
- }
- }
- // Restore / Drain Satiation
- if (interactionSheet.enableSatiationRestore && interactorEntity)
- {
- if (interactorEntity)
- {
- interactorEntity.RestoreSatiation(interactionSheet.satiationToRestore);
- }
- else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
- }
- }
- if (interactionSheet.enableSatiationDrain && interactorEntity)
- {
- if (interactorEntity)
- {
- interactorEntity.DrainSatiation(interactionSheet.satiationToDrain);
- }
- else
- {
- Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
- }
- }
- // Storytelling
- if (interactionSheet.enableJournalEntry && journalController)
- {
- journalController.AddJournalEntry(interactionSheet.addJournalEntryID);
- }
- }
- #endregion Private Methods
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement