Files

124 lines
4.9 KiB
C#

using System.Collections;
using UnityEngine;
namespace BumpCombat.Defense
{
public sealed class Defense25DPreview : MonoBehaviour
{
private const string BodyKey = "Bodies/Fire/T3-Idle";
private const string FlightKey = "Effects/Fire/Meteor-Flight";
private const string ImpactKey = "Effects/Fire/Meteor-Impact";
private const float AuraFrameSeconds = 0.14f;
[SerializeField] private SpriteRenderer body, auraBack, auraFront, meteor;
[SerializeField] private Sprite[] auraBackFrames, auraFrontFrames, meteorFlightFrames, meteorImpactFrames, bodyFrames;
[SerializeField] private Transform groundAnchor, bodyVisual;
[SerializeField] private float flightHeight = 1.7f;
public SpriteRenderer Body => body;
public SpriteRenderer AuraBack => auraBack;
public SpriteRenderer AuraFront => auraFront;
public SpriteRenderer Meteor => meteor;
public Sprite[] AuraBackFrames => auraBackFrames;
public Sprite[] AuraFrontFrames => auraFrontFrames;
public Sprite[] MeteorFlightFrames => meteorFlightFrames;
public Sprite[] MeteorImpactFrames => meteorImpactFrames;
public Sprite[] BodyFrames => bodyFrames;
public Transform GroundAnchor => groundAnchor;
public Transform BodyVisual => bodyVisual;
public float CurrentMeteorHeight { get; private set; }
public Vector2 CurrentMeteorGround { get; private set; }
public void Configure(Sprite[] back, Sprite[] front, Sprite[] flight, Sprite[] impact, Sprite[] character)
{
auraBackFrames = back; auraFrontFrames = front; meteorFlightFrames = flight;
meteorImpactFrames = impact; bodyFrames = character;
}
public static Vector3 ProjectGroundAndHeight(Vector2 groundPosition, float height) =>
new Vector3(groundPosition.x - height, groundPosition.y + height, 0f);
private IEnumerator Start()
{
StartCoroutine(AnimateAura());
StartCoroutine(AnimateBody());
StartCoroutine(MoveTarget());
while (true)
{
yield return new WaitForSeconds(0.25f);
yield return PlayMeteor();
yield return new WaitForSeconds(0.55f);
}
}
private IEnumerator MoveTarget()
{
while (true)
{
Vector3 p = groundAnchor.position;
p.x = Mathf.Sin(Time.time * 0.7f) * 0.65f;
groundAnchor.position = p;
yield return null;
}
}
private IEnumerator AnimateAura()
{
int frame = 0;
while (true)
{
auraBack.sprite = auraBackFrames[frame];
auraFront.sprite = auraFrontFrames[frame];
frame = (frame + 1) % auraBackFrames.Length;
yield return new WaitForSeconds(AuraFrameSeconds);
}
}
private IEnumerator AnimateBody()
{
int frame = 0;
while (true)
{
body.sprite = bodyFrames[frame];
frame = (frame + 1) % bodyFrames.Length;
yield return new WaitForSeconds(DefenseTowerArt.FrameSeconds(BodyKey, frame == 0 ? bodyFrames.Length - 1 : frame - 1));
}
}
private IEnumerator PlayMeteor()
{
CurrentMeteorGround = groundAnchor.position;
meteor.enabled = true;
CurrentMeteorHeight = flightHeight;
float flightDuration = 0f;
for (int i = 0; i < meteorFlightFrames.Length; i++) flightDuration += DefenseTowerArt.FrameSeconds(FlightKey, i);
float elapsed = 0f;
for (int i = 0; i < meteorFlightFrames.Length; i++)
{
meteor.sprite = meteorFlightFrames[i];
float frameSeconds = DefenseTowerArt.FrameSeconds(FlightKey, i);
float frameElapsed = 0f;
while (frameElapsed < frameSeconds)
{
CurrentMeteorHeight = flightHeight * (1f - elapsed / flightDuration);
meteor.transform.position = ProjectGroundAndHeight(CurrentMeteorGround, CurrentMeteorHeight);
float dt = Mathf.Min(Time.deltaTime, frameSeconds - frameElapsed);
frameElapsed += dt;
elapsed += dt;
yield return null;
}
}
CurrentMeteorHeight = 0f;
meteor.transform.position = ProjectGroundAndHeight(CurrentMeteorGround, 0f);
for (int i = 0; i < meteorImpactFrames.Length; i++)
{
meteor.sprite = meteorImpactFrames[i];
yield return new WaitForSeconds(DefenseTowerArt.FrameSeconds(ImpactKey, i));
}
meteor.enabled = false;
}
}
}