Files
tiny_tackle_heroes/Assets/_Project/Scripts/Defense/DefenseSummonUnit.cs
T
2026-09-25 06:27:30 +09:00

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];
}
}
}
}