159 lines
5.9 KiB
C#
159 lines
5.9 KiB
C#
using DG.Tweening;
|
|
using Sirenix.OdinInspector;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Beyond
|
|
{
|
|
public class ScalableSliderController : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
private float maskTopOffset = -0.05f, maxHealthOffset = 1f, vesselRightOffset = 0.15f, fillBackgroundOffset = 0.1f, fillBackgroundTopOffset;
|
|
|
|
[SerializeField]
|
|
private float animationValueChangeThreshold = 0.05f, loadingEffectDelay = 0.5f, effectSpeed = 0.5f, flashDuration = 0.3f;
|
|
|
|
private float scale = 1f;
|
|
private float currentValue = 1f, currentAnimatedValue = 1f;
|
|
|
|
public Image barMask, barFill, barEffectMask, barFillEffect, barFillBackground, barVessel, barDecoration;
|
|
|
|
//for stamina
|
|
[SerializeField]
|
|
private bool useHeightAsWidth;
|
|
|
|
[SerializeField]
|
|
private bool flashBar = true;
|
|
|
|
private bool isAnimating = false;
|
|
|
|
[SerializeField]
|
|
private Vector2 barFillInitialSize;
|
|
|
|
private Color initialColor = new Color(1, 1, 1, 1), flashColor = new Color(1, 1, 1, 0);
|
|
|
|
[SerializeField]
|
|
private float baseSizeScale = 1f;
|
|
|
|
[Button]
|
|
public void Initialize()
|
|
{
|
|
if (useHeightAsWidth)
|
|
{
|
|
barFillInitialSize = new Vector2(barFill.rectTransform.sizeDelta.y - barFill.rectTransform.offsetMax.y, barFill.rectTransform.sizeDelta.x);
|
|
}
|
|
else
|
|
{
|
|
barFillInitialSize = barFill.rectTransform.sizeDelta;
|
|
}
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
//cuz on cutscenes it could break
|
|
isAnimating = false;
|
|
SetValueWithEffectCoroutine(currentValue);
|
|
}
|
|
|
|
[Button]
|
|
public void SetScale(float scale)
|
|
{
|
|
this.scale = scale;
|
|
maxHealthOffset = barFillInitialSize.x * (baseSizeScale * scale - 1);
|
|
barMask.rectTransform.offsetMax = new Vector2(maxHealthOffset, maskTopOffset);
|
|
if (useHeightAsWidth)
|
|
{
|
|
barFill.rectTransform.sizeDelta = new Vector2(barFillInitialSize.y, (barFillInitialSize.x) * scale * baseSizeScale + barFill.rectTransform.offsetMax.y);
|
|
barFillEffect.rectTransform.sizeDelta = new Vector2(barFillInitialSize.y, (barFillInitialSize.x) * scale * baseSizeScale + barFill.rectTransform.offsetMax.y);
|
|
}
|
|
else
|
|
{
|
|
barFill.rectTransform.sizeDelta = new Vector2(barFillInitialSize.x * scale * baseSizeScale, barFillInitialSize.y);
|
|
barFillEffect.rectTransform.sizeDelta = new Vector2(barFillInitialSize.x * scale * baseSizeScale, barFillInitialSize.y);
|
|
}
|
|
barEffectMask.rectTransform.offsetMax = new Vector2(maxHealthOffset, maskTopOffset);
|
|
barFillBackground.rectTransform.sizeDelta = new Vector2(barFillInitialSize.x * scale * baseSizeScale - fillBackgroundOffset, fillBackgroundTopOffset);
|
|
barVessel.rectTransform.offsetMax = new Vector2(maxHealthOffset - vesselRightOffset, barVessel.rectTransform.offsetMax.y);
|
|
}
|
|
|
|
[ExecuteInEditMode]
|
|
[Button]
|
|
public void SetSliderValue(float value)
|
|
{
|
|
if (gameObject.activeInHierarchy)
|
|
{
|
|
StartCoroutine(SetValueWithEffectCoroutine(value));
|
|
}
|
|
}
|
|
|
|
[Button]
|
|
public void TakeDamage()
|
|
{
|
|
SetSliderValue(currentValue - 0.1f);
|
|
}
|
|
|
|
[Button]
|
|
public void HealDamage()
|
|
{
|
|
SetSliderValue(currentValue + 0.1f);
|
|
}
|
|
|
|
[ExecuteInEditMode]
|
|
private IEnumerator SetValueWithEffectCoroutine(float value)
|
|
{
|
|
float healthOffset = barFillInitialSize.x * (baseSizeScale * scale - 1);
|
|
float currentHealthOffset = healthOffset;
|
|
healthOffset -= (barFillInitialSize.x + healthOffset) * (1 - value);
|
|
float difference = currentValue - value;
|
|
if (flashBar && difference > animationValueChangeThreshold)
|
|
{
|
|
StartCoroutine(FlashBarColor());
|
|
}
|
|
currentValue = value;
|
|
barMask.rectTransform.offsetMax = new Vector2(healthOffset, maskTopOffset);
|
|
if ((difference < animationValueChangeThreshold) && !isAnimating)
|
|
{
|
|
currentAnimatedValue = currentValue;
|
|
barEffectMask.rectTransform.offsetMax = new Vector2(currentHealthOffset - (barFillInitialSize.x + currentHealthOffset) * (1 - currentAnimatedValue), maskTopOffset);
|
|
yield break;
|
|
}
|
|
isAnimating = true;
|
|
|
|
yield return new WaitForSeconds(loadingEffectDelay);
|
|
|
|
if (difference > animationValueChangeThreshold)
|
|
{
|
|
while (currentAnimatedValue > currentValue)
|
|
{
|
|
currentAnimatedValue -= Time.deltaTime * effectSpeed;
|
|
barEffectMask.rectTransform.offsetMax = new Vector2(currentHealthOffset - (barFillInitialSize.x + currentHealthOffset) * (1 - currentAnimatedValue), maskTopOffset);
|
|
yield return new WaitForEndOfFrame();
|
|
}
|
|
isAnimating = false;
|
|
}
|
|
}
|
|
|
|
private IEnumerator FlashBarColor()
|
|
{
|
|
float time = 0f;
|
|
while (time < flashDuration)
|
|
{
|
|
barFillBackground.color = Color.Lerp(Color.white, Color.black, time / flashDuration);
|
|
time += Time.deltaTime;
|
|
yield return new WaitForEndOfFrame();
|
|
}
|
|
|
|
time = 0f;
|
|
while (time < flashDuration)
|
|
{
|
|
barFillBackground.color = Color.Lerp(Color.black, Color.white, time / flashDuration);
|
|
time += Time.deltaTime;
|
|
yield return new WaitForEndOfFrame();
|
|
}
|
|
barFillBackground.color = Color.white;
|
|
}
|
|
}
|
|
} |