using UnityEngine; namespace BumpCombat.Defense { [DisallowMultipleComponent] public sealed class DefenseSummonUnit : MonoBehaviour { private static Sprite[] idleFrames; private static Sprite[] attackFrames; private DefenseTower owner; private DefensePrototypeController controller; private Vector2 anchorLocalPosition; private SpriteRenderer spriteRenderer; private float attackCooldown; private float attackAnimationTime = -1f; public void Configure( DefenseTower tower, DefensePrototypeController prototypeController, Vector2 localAnchor) { owner = tower; controller = prototypeController; anchorLocalPosition = localAnchor; spriteRenderer = gameObject.AddComponent(); idleFrames ??= Resources.LoadAll("Tutorial/Swordsman_Idle"); attackFrames ??= Resources.LoadAll("Tutorial/Swordsman_BumpAttack-v1"); if (idleFrames.Length > 0) { spriteRenderer.sprite = idleFrames[0]; } spriteRenderer.color = new Color32(255, 234, 137, 255); spriteRenderer.sortingOrder = 11; float scale = owner.Tier == 4 && owner.Branch == DefenseTowerBranch.First ? 1.35f : 0.9f; transform.localScale = new Vector3(scale, scale, 1f); } private void Update() { UpdateAttackSprite(); 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) { transform.position = Vector2.MoveTowards( transform.position, anchor, controller.Tuning.SummonUnitMoveSpeed * Time.deltaTime); return; } Vector2 targetPosition = target.transform.position; spriteRenderer.flipX = targetPosition.x < transform.position.x; transform.position = Vector2.MoveTowards( transform.position, targetPosition, controller.Tuning.SummonUnitMoveSpeed * Time.deltaTime); 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.Length == 0) { return; } attackAnimationTime = 0f; spriteRenderer.sprite = attackFrames[0]; } private void UpdateAttackSprite() { if (attackAnimationTime < 0f || attackFrames == null || attackFrames.Length == 0) { return; } attackAnimationTime += Time.deltaTime; int frame = Mathf.FloorToInt(attackAnimationTime * 12f); if (frame >= attackFrames.Length) { attackAnimationTime = -1f; if (idleFrames != null && idleFrames.Length > 0) { spriteRenderer.sprite = idleFrames[0]; } return; } spriteRenderer.sprite = attackFrames[frame]; } } }