RobotGames
Member
In my current game, Crypt Hunter, I have two types of health pickups. small that the player just picks up and large where the player interacts in order to get the health. Here is the interactable I created for the large health. I use them to give the player a percentage of their current health so the pickups will level up with the player. You could easily change this to a flat amount or adjust other attributes like Mana or Shield or whatever. I copped quite a bit of this from Justin's code and tried to follow his conventions just for consistencies. I send a message when the item is interacted to trigger the removal of the item which I animate in another behavior.
I didn't make a fancy inspector, sorry!
I didn't make a fancy inspector, sorry!
Code:
using UnityEngine;
using UnityEngine.Events;
using Opsive.UltimateCharacterController.Traits;
using Opsive.UltimateCharacterController.Utility;
using Opsive.UltimateCharacterController.Audio;
using Opsive.UltimateCharacterController.Events;
public class HealthInteractable : MonoBehaviour, IInteractableTarget, IInteractableMessage
{
[Tooltip("Health provided as a percentage.")]
[Range(0.0f, 1.0f)]
[SerializeField] protected float m_health = 1;
[Tooltip("The UI message that should be displayed.")]
[SerializeField] protected string m_BoolEnabledMessage;
[Tooltip("An array of audio clips that can be played when the interaction starts.")]
[SerializeField] protected AudioClip[] m_InteractAudioClips;
[Tooltip("Unity event invoked when the interaction occurs.")]
[SerializeField] protected UnityEvent m_OnUseEvent;
public float Health { get { return m_health; } set { m_health = value; } }
public string EnanabledMessage { get { return m_BoolEnabledMessage; } set { m_BoolEnabledMessage = value; } }
public AudioClip[] InteractAudioClips { get { return m_InteractAudioClips; } set { m_InteractAudioClips = value; } }
public UnityEvent OnUseEvent { get { return m_OnUseEvent; } set { m_OnUseEvent = value; } }
private GameObject m_GameObject;
private bool m_HasInteracted;
private int m_AudioClipIndex = -1;
private void Awake()
{
m_GameObject = gameObject;
}
/// <summary>
/// Can the target be interacted with?
/// </summary>
/// <param name="character">The character that wants to interactact with the target.</param>
/// <returns>True if the target can be interacted with.</returns>
public bool CanInteract(GameObject character)
{
return !m_HasInteracted;
}
/// <summary>
/// Interact with the target.
/// </summary>
/// <param name="character">The character that wants to interactact with the target.</param>
public void Interact(GameObject character)
{
var health = character.GetCachedParentComponent<Health>();
var attributeManager = character.GetCachedParentComponent<AttributeManager>();
if (health != null && attributeManager != null && health.IsAlive())
{
var healthName = health.HealthAttributeName;
var maxHealth = attributeManager.GetAttribute(healthName).MaxValue;
health.Heal(Mathf.FloorToInt(maxHealth * m_health));
}
if (m_InteractAudioClips.Length > 0)
{
// Sequentually switch between audio clips.
m_AudioClipIndex = (m_AudioClipIndex + 1) % m_InteractAudioClips.Length;
AudioManager.Play(m_GameObject, m_InteractAudioClips[m_AudioClipIndex]);
}
m_HasInteracted = true;
EventHandler.ExecuteEvent(m_GameObject, "OnHealthInteraction");
if (m_OnUseEvent != null)
m_OnUseEvent.Invoke();
}
public string AbilityMessage()
{
return m_BoolEnabledMessage;
}
}