Сообщение от Crystal
Не стоит пакс, я с массивами работаю где мне это удобно,
массив не является для меня чем-то новым и непонятным )
|
Тем не менее я уже сделал. В аттаче видео результата и проект (Unity 2019.4.10). Собственно код получился вот такой:
using UnityEngine;
public class HealthBarAnimated : MonoBehaviour
{
public int health;
public int maxHealth;
public Color32 normalColor;
public Color32 dangerColor;
[System.Serializable]
public class AnimatedElement
{
public SpriteRenderer sprite; // анимируемый спрайт
public Vector3 startPosition; // начальная позиция анимации
public Vector3 endPosition; // конечная позиция анимации
public float positionAnimationSpeed = 1; // скорость анимации позиции
public bool animatePositionAsHealthPercent = false; // анимировать позицию на основе процента жизней
private float positionAnimationTime; // текущее время анимации позиции
public bool animateColor = true; // анимировать цвет
public AnimationCurve alphaAnimationCurve; // кривая анимации альфы (можно конечно было использовать Mathf.SmoothStep, но решил показать еще один способ анимации)
public float alphaAnimationSpeed = 1; // скорость анимации альфы
private float alphaAnimationTime; // время анимации альфы
public bool animateHealthPercentScale = false; // анимировать скейл на основе процента жизней
public AnimationCurve healthPercentScaleAnimationCurve; // кривая интерполяции анимации масштаба
public Vector3 healthPercentStartScale; // начальный масштаб
public Vector3 healthPercentEndScale; // конечный масштаб
public float healthColorTransitionStart; // начало зоны перехода из нормального цвета в цвет опасности
public float healthColorTransitionEnd; // конец зоны перехода из нормального цвета в цвет опасности
public void Init()
{
// рандомизация начальных позиций анимаций
positionAnimationTime = Random.value;
alphaAnimationTime = Random.value;
}
// обновление состояния спрайта
public void Update(float healthPercent, Color32 normalColor, Color32 dangerColor, float deltaTime)
{
if (animatePositionAsHealthPercent)
{
sprite.transform.localPosition = Vector3.Lerp(startPosition, endPosition, healthPercent);
}
else
{
positionAnimationTime += deltaTime * positionAnimationSpeed;
sprite.transform.localPosition = Vector3.Lerp(startPosition, endPosition, Mathf.PingPong(positionAnimationTime, 1));
}
if (animateHealthPercentScale)
{
sprite.transform.localScale = Vector3.Lerp(healthPercentStartScale, healthPercentEndScale, healthPercent);
}
if (animateColor)
{
var healthPercentClamped = Mathf.Clamp(healthPercent, healthColorTransitionStart, healthColorTransitionEnd);
var healthColorT = (healthPercentClamped - healthColorTransitionStart) / (healthColorTransitionEnd - healthColorTransitionStart);
var color = Color.Lerp(dangerColor, normalColor, healthColorT);
alphaAnimationTime += deltaTime * alphaAnimationSpeed;
color.a = alphaAnimationCurve.Evaluate(Mathf.PingPong(alphaAnimationTime, 1));
sprite.color = color;
}
}
}
// массив анимируемых объектов
public AnimatedElement[] animatedElements;
void Start()
{
// инициализация элементов
for (int i = 0; i < animatedElements.Length; i++)
{
animatedElements[i].Init();
}
}
void Update()
{
if (health < 0) health = 0;
if (health > maxHealth) health = maxHealth;
var healthPercent = health / (float)maxHealth;
// обновление анимации элементов
for (int i = 0; i < animatedElements.Length; i++)
{
animatedElements[i].Update(healthPercent, normalColor, dangerColor, Time.deltaTime);
}
}
}
По времени заняло пол часа кода, пол часа настройки.