/// --------------------------------------------- /// Ultimate Character Controller /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.UltimateCharacterController.UI { using Opsive.Shared.Events; using UnityEngine; using UnityEngine.UI; /// /// The HealthFlashMonitor will show a full screen flash when the character takes damage or is healed. /// public class HealthFlashMonitor : CharacterMonitor { /// /// Stores the flash settings. /// [System.Serializable] public struct Flash { [Tooltip("Can the flash be activated?")] [SerializeField] private bool m_CanActivate; [Tooltip("The amount of time the flash should be fully visible for.")] [SerializeField] private float m_VisiblityDuration; [Tooltip("The amount of time it takes the flash UI to fade.")] [SerializeField] private float m_FadeDuration; [Tooltip("The color of the image flash.")] [SerializeField] private Color m_Color; [Tooltip("The image of the flash.")] [SerializeField] private Sprite m_Sprite; public bool CanActivate { get { return m_CanActivate; } } public float VisiblityDuration { get { return m_VisiblityDuration; } } public float FadeDuration { get { return m_FadeDuration; } } public Color Color { get { return m_Color; } } public Sprite Sprite { get { return m_Sprite; } } /// /// Constructor for the flash struct. /// /// Can the flash be activated? /// The amount of time the flash should be fully visible for. /// The amount of time it takes the flash UI to fade. /// The amount of time it takes the flash UI to fade. public Flash(bool canActivate, Color color, float visibilityDuration, float fadeDuration) { m_CanActivate = canActivate; m_Color = color; m_VisiblityDuration = visibilityDuration; m_FadeDuration = fadeDuration; m_Sprite = null; } } [Tooltip("The flash when the character is damaged.")] [SerializeField] protected Flash m_DamageFlash = new Flash(true, new Color(1, 0, 0, 0.7f), 1.5f, 1f); [Tooltip("The flash when the character is healed.")] [SerializeField] protected Flash m_HealFlash = new Flash(true, new Color(1, 1, 1, 0.2f), 0.05f, 0.2f); public Flash DamageFlash { get { return m_DamageFlash; } set { m_DamageFlash = value; } } public Flash HealFlash { get { return m_HealFlash; } set { m_HealFlash = value; } } private GameObject m_GameObject; private Image m_FlashImage; private float m_FlashDisplayTime; private Flash m_ActiveFlash; /// /// Initialize the default values. /// protected override void Awake() { base.Awake(); m_FlashImage = GetComponentInChildren(); if (m_FlashImage == null) { Debug.LogError("Error: Unable to find an Image component for the damage flash. Disabling."); return; } m_FlashImage.color = Color.clear; m_GameObject = gameObject; m_GameObject.SetActive(false); } /// /// Attaches the monitor to the specified character. /// /// The character to attach the monitor to. protected override void OnAttachCharacter(GameObject character) { if (m_Character != null) { EventHandler.UnregisterEvent(m_Character, "OnHealthDamage", OnDamage); EventHandler.UnregisterEvent(m_Character, "OnHealthHeal", OnHeal); } base.OnAttachCharacter(character); if (m_Character == null || m_GameObject == null) { return; } EventHandler.RegisterEvent(m_Character, "OnHealthDamage", OnDamage); EventHandler.RegisterEvent(m_Character, "OnHealthHeal", OnHeal); m_GameObject.SetActive(false); } /// /// The object has taken damage. /// /// The amount of damage taken. /// The position of the damage. /// The amount of force applied to the object while taking the damage. /// The GameObject that did the damage. /// The Collider that was hit. private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider) { if (!m_DamageFlash.CanActivate) { return; } // Show the flash image. m_ActiveFlash = m_DamageFlash; m_FlashImage.color = m_DamageFlash.Color; m_FlashImage.sprite = m_DamageFlash.Sprite; m_FlashDisplayTime = Time.time; // Allow the flash to fade. m_GameObject.SetActive(true); } /// /// The object has healed. /// /// The amount that the object was healed by. private void OnHeal(float amount) { if (!m_HealFlash.CanActivate) { return; } // Show the flash image. m_ActiveFlash = m_HealFlash; m_FlashImage.color = m_HealFlash.Color; m_FlashImage.sprite = m_HealFlash.Sprite; m_FlashDisplayTime = Time.time; // Allow the flash to fade. m_GameObject.SetActive(true); } /// /// Fade the flash. /// private void Update() { // Update the flash alpha. var alpha = Mathf.Min((m_ActiveFlash.FadeDuration - (Time.time - (m_FlashDisplayTime + m_ActiveFlash.VisiblityDuration))) / m_ActiveFlash.FadeDuration, 1) * m_ActiveFlash.Color.a; var color = m_FlashImage.color; color.a = alpha; m_FlashImage.color = color; if (alpha <= 0) { m_GameObject.SetActive(false); } } /// /// Can the UI be shown? /// /// True if the UI can be shown. protected override bool CanShowUI() { return m_FlashImage.color.a > 0; } } }