using Cal.DataTable; using System; using System.Collections.Generic; using UnityEngine; namespace ET { public class FollowTeamLeaderNode : AINode { private const float TeamDistanceBetweenUnits = 0.8f; public override bool Check(Unit unit) { if (unit.IsTeamLeader) return false; var leader = MapUnitComponent.Instance.Get(unit.TeamLeaderId); if (!leader) return false; UnitScene unitScene = leader.GetComponent(); return unitScene.isMoved; } public override async ETVoid Run(Unit unit, ETCancellationToken cancelToken) { while (true) { try { if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(unit.Id)?.NickName} ({unit.Id})】跟随队长"); var leader = MapUnitComponent.Instance.Get(unit.TeamLeaderId); if (!leader) return; UnitScene unitScene = unit.GetComponent(); UnitScene leaderUnitScene = leader.GetComponent(); var target = leaderUnitScene.targetPos; Vector2 delta = CalucateDistanceXandY(unitScene.Position, target); Team team = TeamComponent.Instance.Get(unit.TeamLeaderId); int index = team.GetIndex(unit.Id); Vector2 targetPos = new(target.x - delta.x * index, target.y - delta.y * index); var ret = await MoveHelper.MoveTo(unit, targetPos, cancelToken); // 移动到目标点, 返回false表示协程取消 if (!ret) return; ret = await TimerComponent.Instance.WaitAsync(300, cancelToken); if (!ret) return; } catch (Exception e) { Log.Error(e); } } } private static Vector2 CalucateDistanceXandY(Vector2 posA, Vector2 posB) { float dx = posB.x - posA.x; int positive = dx >= 0 ? 1 : -1; float gradient = (posB.y - posA.y) / dx; return new Vector2(positive * TeamDistanceBetweenUnits / Mathf.Sqrt(1 + gradient * gradient) , positive * gradient * TeamDistanceBetweenUnits / Mathf.Sqrt(1 + gradient * gradient)); } } }