using System; using UnityEngine; using UnityEngine.UI; using DuloGames.UI.Tweens; using System.Collections; namespace DuloGames.UI { [ExecuteInEditMode, RequireComponent(typeof(CanvasGroup))] public class UICastBar : MonoBehaviour { [Serializable] public enum DisplayTime { Elapsed, Remaining } [Serializable] public enum Transition { Instant, Fade } [Serializable] public class ColorStage { public Color fillColor = Color.white; public Color titleColor = Color.white; public Color timeColor = Color.white; } [SerializeField] private UIProgressBar m_ProgressBar; [SerializeField] private Text m_TitleLabel; [SerializeField] private Text m_TimeLabel; [SerializeField] private DisplayTime m_DisplayTime = DisplayTime.Remaining; [SerializeField] private string m_TimeFormat = "0.0 sec"; [SerializeField] private Text m_FullTimeLabel; [SerializeField] private string m_FullTimeFormat = "0.0 sec"; [SerializeField] private bool m_UseSpellIcon; [SerializeField] private GameObject m_IconFrame; [SerializeField] private Image m_IconImage; [SerializeField] private Image m_FillImage; [SerializeField] private ColorStage m_NormalColors = new ColorStage(); [SerializeField] private ColorStage m_OnInterruptColors = new ColorStage(); [SerializeField] private ColorStage m_OnFinishColors = new ColorStage(); [SerializeField] private Transition m_InTransition = Transition.Instant; [SerializeField] private float m_InTransitionDuration = 0.1f; [SerializeField] private bool m_BrindToFront = true; [SerializeField] private Transition m_OutTransition = Transition.Fade; [SerializeField] private float m_OutTransitionDuration = 0.1f; [SerializeField] private float m_HideDelay = 0.3f; private bool m_IsCasting = false; /// /// Gets a value indicating whether this cast bar is casting. /// /// true if this instance is casting; otherwise, false. public bool IsCasting { get { return this.m_IsCasting; } } private float currentCastDuration = 0f; private float currentCastEndTime = 0f; private CanvasGroup m_CanvasGroup; /// /// Gets the canvas group. /// /// The canvas group. public CanvasGroup canvasGroup { get { return this.m_CanvasGroup; } } // Tween controls [NonSerialized] private readonly TweenRunner m_FloatTweenRunner; // Called by Unity prior to deserialization, // should not be called by users protected UICastBar() { if (this.m_FloatTweenRunner == null) this.m_FloatTweenRunner = new TweenRunner(); this.m_FloatTweenRunner.Init(this); } protected virtual void Awake() { this.m_CanvasGroup = this.gameObject.GetComponent(); } protected virtual void Start() { if (this.isActiveAndEnabled) { // Apply the normal color stage this.ApplyColorStage(this.m_NormalColors); // Hide the bar only while the application is playing if (Application.isPlaying) { // Hide the icon frame if (this.m_IconFrame != null) this.m_IconFrame.SetActive(false); // Hide the cast bar this.Hide(true); } } } #if UNITY_EDITOR protected void OnValidate() { // Apply the normal color stage if (this.isActiveAndEnabled) this.ApplyColorStage(this.m_NormalColors); } #endif /// /// Applies the color stages. /// /// Stage. public virtual void ApplyColorStage(ColorStage stage) { if (this.m_FillImage != null) this.m_FillImage.canvasRenderer.SetColor(stage.fillColor); if (this.m_TitleLabel != null) this.m_TitleLabel.canvasRenderer.SetColor(stage.titleColor); if (this.m_TimeLabel != null) this.m_TimeLabel.canvasRenderer.SetColor(stage.timeColor); } /// /// Show this cast bar. /// public void Show() { // Call show with a transition this.Show(false); } /// /// Show this cast bar. /// /// If set to true instant. public virtual void Show(bool instant) { // Bring to the front if (this.m_BrindToFront) UIUtility.BringToFront(this.gameObject); // Do the transition if (instant || this.m_InTransition == Transition.Instant) { // Set the canvas group alpha this.m_CanvasGroup.alpha = 1f; } else { // Start a tween this.StartAlphaTween(1f, this.m_InTransitionDuration, true); } } /// /// Hide this cast bar. /// public void Hide() { // Call hide with a transition this.Hide(false); } /// /// Hide this cast bar. /// /// If set to true instant. public virtual void Hide(bool instant) { if (instant || this.m_OutTransition == Transition.Instant) { // Set the canvas group alpha this.m_CanvasGroup.alpha = 0f; // Raise the on hide tween finished event this.OnHideTweenFinished(); } else { // Start a tween this.StartAlphaTween(0f, this.m_OutTransitionDuration, true); } } /// /// Starts alpha tween. /// /// Target alpha. /// Duration. /// If set to true ignore time scale. public void StartAlphaTween(float targetAlpha, float duration, bool ignoreTimeScale) { if (this.m_CanvasGroup == null) return; var floatTween = new FloatTween { duration = duration, startFloat = this.m_CanvasGroup.alpha, targetFloat = targetAlpha }; floatTween.AddOnChangedCallback(SetCanvasAlpha); floatTween.AddOnFinishCallback(OnHideTweenFinished); floatTween.ignoreTimeScale = ignoreTimeScale; this.m_FloatTweenRunner.StartTween(floatTween); } /// /// Sets the canvas alpha. /// /// Alpha. protected void SetCanvasAlpha(float alpha) { if (this.m_CanvasGroup == null) return; // Set the alpha this.m_CanvasGroup.alpha = alpha; } /// /// Raises the hide tween finished event. /// protected virtual void OnHideTweenFinished() { // Hide the icon frame if (this.m_IconFrame != null) this.m_IconFrame.SetActive(false); // Unset the icon image sprite if (this.m_IconImage != null) this.m_IconImage.sprite = null; } /// /// Sets the fill amount. /// /// Amount. public void SetFillAmount(float amount) { if (this.m_ProgressBar != null) this.m_ProgressBar.fillAmount = amount; } IEnumerator AnimateCast() { // Update the text if (this.m_TimeLabel != null) this.m_TimeLabel.text = ((this.m_DisplayTime == DisplayTime.Elapsed) ? 0f.ToString(this.m_TimeFormat) : this.currentCastDuration.ToString(this.m_TimeFormat)); // Get the timestamp float startTime = (this.currentCastEndTime > 0f) ? (this.currentCastEndTime - this.currentCastDuration) : Time.time; // Fade In the notification while (Time.time < (startTime + this.currentCastDuration)) { float RemainingTime = (startTime + this.currentCastDuration) - Time.time; float ElapsedTime = this.currentCastDuration - RemainingTime; float ElapsedTimePct = ElapsedTime / this.currentCastDuration; // Update the elapsed cast time value if (this.m_TimeLabel != null) this.m_TimeLabel.text = ((this.m_DisplayTime == DisplayTime.Elapsed) ? ElapsedTime.ToString(this.m_TimeFormat) : RemainingTime.ToString(this.m_TimeFormat)); // Update the fill sprite this.SetFillAmount(ElapsedTimePct); yield return 0; } // Update the fill sprite to full this.SetFillAmount(1f); // Make sure it's maxed if (this.m_TimeLabel != null) this.m_TimeLabel.text = ((this.m_DisplayTime == DisplayTime.Elapsed) ? this.currentCastDuration.ToString(this.m_TimeFormat) : 0f.ToString(this.m_TimeFormat)); // Call that we finished this.OnFinishedCasting(); // Hide with a delay this.StartCoroutine("DelayHide"); } IEnumerator DelayHide() { // Wait for the hide delay yield return new WaitForSeconds(this.m_HideDelay); // Do not show the casting anymore this.Hide(); } /// /// Starts the casting of the specified spell. /// /// Spell info. /// Duration. /// End time. public virtual void StartCasting(UISpellInfo spellInfo, float duration, float endTime) { // Make sure we can start casting it if (this.m_IsCasting) return; // Stop the coroutine might be still running on the hide delay this.StopCoroutine("AnimateCast"); this.StopCoroutine("DelayHide"); // Apply the normal colors this.ApplyColorStage(this.m_NormalColors); // Change the fill pct this.SetFillAmount(0f); // Set the spell name if (this.m_TitleLabel != null) this.m_TitleLabel.text = spellInfo.Name; // Set the full time cast text if (this.m_FullTimeLabel != null) this.m_FullTimeLabel.text = spellInfo.CastTime.ToString(this.m_FullTimeFormat); // Set the icon if we have enabled icons if (this.m_UseSpellIcon) { // Check if we have a sprite if (spellInfo.Icon != null) { // Check if the icon image is set if (this.m_IconImage != null) this.m_IconImage.sprite = spellInfo.Icon; // Enable the frame if (this.m_IconFrame != null) this.m_IconFrame.SetActive(true); } } // Set some info about the cast this.currentCastDuration = duration; this.currentCastEndTime = endTime; // Define that we start casting animation this.m_IsCasting = true; // Show the cast bar this.Show(); // Start the cast animation this.StartCoroutine("AnimateCast"); } /// /// Interrupts the current cast if any. /// public virtual void Interrupt() { if (this.m_IsCasting) { // Stop the coroutine if it's assigned this.StopCoroutine("AnimateCast"); // No longer casting this.m_IsCasting = false; // Apply the interrupt colors this.ApplyColorStage(this.m_OnInterruptColors); // Hide with a delay this.StartCoroutine("DelayHide"); } } protected void OnFinishedCasting() { // Define that we are no longer casting this.m_IsCasting = false; // Apply the finish colors this.ApplyColorStage(this.m_OnFinishColors); } } }