158 lines
5.9 KiB
C#
158 lines
5.9 KiB
C#
using UnityEngine;
|
|
|
|
namespace BumpCombat.Defense
|
|
{
|
|
[DisallowMultipleComponent]
|
|
public sealed class DefenseSummonUnit : MonoBehaviour
|
|
{
|
|
private Sprite[] idleFrames;
|
|
private Sprite[] attackFrames;
|
|
private string idleKey;
|
|
private string attackKey;
|
|
private float spriteFrameTime;
|
|
private int spriteFrame;
|
|
private bool playingAttack;
|
|
private bool isWalking;
|
|
private string walkKey;
|
|
private Sprite[] walkFrames;
|
|
|
|
private DefenseTower owner;
|
|
private DefensePrototypeController controller;
|
|
private Vector2 anchorLocalPosition;
|
|
private SpriteRenderer spriteRenderer;
|
|
private float attackCooldown;
|
|
|
|
public void Configure(
|
|
DefenseTower tower,
|
|
DefensePrototypeController prototypeController,
|
|
Vector2 localAnchor)
|
|
{
|
|
owner = tower;
|
|
controller = prototypeController;
|
|
anchorLocalPosition = localAnchor;
|
|
spriteRenderer = gameObject.AddComponent<SpriteRenderer>();
|
|
spriteRenderer.color = Color.white;
|
|
spriteRenderer.sortingOrder = 11;
|
|
RefreshArt();
|
|
}
|
|
|
|
public void RefreshArt()
|
|
{
|
|
if (spriteRenderer == null || owner == null)
|
|
{
|
|
return;
|
|
}
|
|
string family = owner.Tier == 4 && owner.Branch == DefenseTowerBranch.First
|
|
? "GiantSlime"
|
|
: owner.Tier == 4 && owner.Branch == DefenseTowerBranch.Second
|
|
? "LavaSlime" : "Slime";
|
|
idleKey = $"Summons/{family}/Idle";
|
|
attackKey = $"Summons/{family}/Attack01";
|
|
walkKey = $"Summons/{family}/Walk";
|
|
idleFrames = DefenseTowerArt.Load(idleKey);
|
|
attackFrames = DefenseTowerArt.Load(attackKey);
|
|
walkFrames = DefenseTowerArt.Load(walkKey);
|
|
spriteFrame = 0;
|
|
spriteFrameTime = 0f;
|
|
playingAttack = false;
|
|
if (idleFrames.Length > 0)
|
|
{
|
|
spriteRenderer.sprite = idleFrames[0];
|
|
}
|
|
float scale = family == "GiantSlime" ? 1.55f
|
|
: family == "LavaSlime" ? 1.15f : 1.1f;
|
|
transform.localScale = new Vector3(scale, scale, 1f);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
UpdateSpriteAnimation();
|
|
if (owner == null
|
|
|| !owner.isActiveAndEnabled
|
|
|| controller == null
|
|
|| !controller.CanOperateTowers)
|
|
{
|
|
return;
|
|
}
|
|
|
|
attackCooldown = Mathf.Max(0f, attackCooldown - Time.deltaTime);
|
|
Vector2 anchor = owner.transform.TransformPoint(anchorLocalPosition);
|
|
DefenseRouteAgent target = controller.FindNearestTarget(
|
|
anchor,
|
|
controller.Tuning.SummonAreaRadius,
|
|
DefenseTowerKind.Summon);
|
|
if (target == null)
|
|
{
|
|
Vector2 previous = transform.position;
|
|
transform.position = Vector2.MoveTowards(
|
|
previous, anchor, controller.Tuning.SummonUnitMoveSpeed * Time.deltaTime);
|
|
isWalking = ((Vector2)transform.position - previous).sqrMagnitude > 0.000001f;
|
|
return;
|
|
}
|
|
|
|
Vector2 targetPosition = target.transform.position;
|
|
spriteRenderer.flipX = targetPosition.x < transform.position.x;
|
|
Vector2 previousPosition = transform.position;
|
|
transform.position = Vector2.MoveTowards(
|
|
previousPosition, targetPosition,
|
|
controller.Tuning.SummonUnitMoveSpeed * Time.deltaTime);
|
|
isWalking = ((Vector2)transform.position - previousPosition).sqrMagnitude > 0.000001f;
|
|
float attackRange = controller.Tuning.SummonAttackRange
|
|
* (owner.Tier == 4 && owner.Branch == DefenseTowerBranch.Second ? 2.5f : 1f);
|
|
if (attackCooldown <= 0f
|
|
&& (targetPosition - (Vector2)transform.position).sqrMagnitude
|
|
<= attackRange * attackRange
|
|
&& owner.TryAttack(target))
|
|
{
|
|
PlayAttackSprite();
|
|
owner.ShowSummonAttackEffect(transform.position, targetPosition);
|
|
attackCooldown = controller.Tuning.SummonAttackInterval
|
|
/ (1f + 0.15f * (owner.Tier - 1))
|
|
* controller.GetTowerAttackIntervalMultiplier(owner);
|
|
}
|
|
}
|
|
|
|
private void PlayAttackSprite()
|
|
{
|
|
if (attackFrames == null || attackFrames.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
playingAttack = true;
|
|
spriteFrameTime = 0f;
|
|
spriteFrame = 0;
|
|
spriteRenderer.sprite = attackFrames[0];
|
|
}
|
|
|
|
private void UpdateSpriteAnimation()
|
|
{
|
|
Sprite[] frames = playingAttack ? attackFrames : isWalking ? walkFrames : idleFrames;
|
|
string key = playingAttack ? attackKey : isWalking ? walkKey : idleKey;
|
|
if (spriteRenderer == null || frames == null || frames.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
spriteFrameTime += Time.deltaTime;
|
|
while (spriteFrameTime >= DefenseTowerArt.FrameSeconds(key, spriteFrame))
|
|
{
|
|
spriteFrameTime -= DefenseTowerArt.FrameSeconds(key, spriteFrame);
|
|
spriteFrame++;
|
|
if (spriteFrame >= frames.Length)
|
|
{
|
|
if (playingAttack)
|
|
{
|
|
playingAttack = false;
|
|
spriteFrame = 0;
|
|
frames = idleFrames;
|
|
key = idleKey;
|
|
}
|
|
else
|
|
{
|
|
spriteFrame = 0;
|
|
}
|
|
}
|
|
spriteRenderer.sprite = frames[spriteFrame];
|
|
}
|
|
}
|
|
}
|
|
} |