ThreeKingdomsSlingshot/Assets/Scripts/Runtime/EnemyAI.cs

56 lines
2.1 KiB
C#
Raw Normal View History

using System.Collections.Generic;
using UnityEngine;
namespace TKS
{
/// <summary>적군 슬링샷 결정: 가장 가까운 아군을 향해 당기고, 정확도에 따라 흔들린다.</summary>
public static class EnemyAI
{
public static Vector2 Decide(Unit e, IReadOnlyList<Unit> targets, float accuracy, System.Random rng, Board board)
{
Unit nearest = null;
float best = float.MaxValue;
for (int i = 0; i < targets.Count; i++)
{
var t = targets[i];
if (!t.IsAlive) continue;
float d = Vector2.Distance(e.Position, t.Position);
if (d < best)
{
best = d;
nearest = t;
}
}
if (nearest == null) return e.Position;
Vector2 toT = nearest.Position - e.Position;
float dist = toT.magnitude;
Vector2 dir = dist > 0.001f ? toT / dist : Vector2.up;
Vector2 target;
if (dist <= e.SlingMaxDistance)
{
target = nearest.Position; // 최종 목표점 명중 시도
}
else
{
target = e.Position + dir * e.SlingMaxDistance; // 접근(궁병은 사거리 안이면 이동 후 사격)
}
if (rng.NextDouble() > accuracy)
{
float ang = ((float)rng.NextDouble() * 2f - 1f) * 22f * Mathf.Deg2Rad;
float cs = Mathf.Cos(ang);
float sn = Mathf.Sin(ang);
Vector2 rd = new Vector2(dir.x * cs - dir.y * sn, dir.x * sn + dir.y * cs);
float len = (target - e.Position).magnitude * (0.75f + 0.5f * (float)rng.NextDouble());
target = e.Position + rd * Mathf.Min(len, e.SlingMaxDistance);
}
Vector2 v = target - e.Position;
if (v.magnitude > e.SlingMaxDistance) v = v.normalized * e.SlingMaxDistance;
return board.ClampInside(e.Position + v, e.Radius);
}
}
}