using System; using System.Collections.Generic; using System.Text; using UnityEngine; namespace ET { public static class MoveHelper { public const float AtkDis = 2.7f * 2.7f; private const float TeamDistanceBetweenUnits = 0.8f; public static void MoveTo(Unit unit, Vector2 target){ UnitScene unitScene = unit.GetComponent(); Vector2 pos = unitScene.Position; int yAngle = pos.x<=target.x?0:180; MoveTo(unit,target,yAngle).Coroutine(); } public static async ETVoid MoveTo(Unit unit, Vector2 target, int yAngle) { try { Team team = TeamComponent.Instance.Get(unit.TeamLeaderId); if (team == null) { Log.Error($"team id = {unit.TeamLeaderId} is null when MoveTo({target})"); return; } int index = 0; foreach (var u in team.GetUnits()) { if (u.IsTransfer) continue; if (u.IsTeamLeader) { FindPathMoveToAsync(u, target).Coroutine(); u.GetComponent().YAngle = yAngle; } else { await TimerComponent.Instance.WaitAsync(300); UnitScene unitScene = u.GetComponent(); Vector2 delta = CalucateDistanceXandY(unitScene.Position, target); Vector2 targetPos = new Vector2(target.x - delta.x * ++index, target.y - delta.y * index); FindPathMoveToAsync(u, targetPos).Coroutine(); unitScene.YAngle = yAngle; } } } 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)); } // 可以多次调用,多次调用的话会取消上一次的协程 public static async ETTask FindPathMoveToAsync(this Unit unit, Vector3 target, ETCancellationToken cancellationToken = null) { float speed = ConstDefine.MoveSpeed; if (speed < 0.001) { SendStop(unit,-1); return; } using var list = ListComponent.Create(); UnitScene unitScene = unit.GetComponent(); list.List.Add(unitScene.Position); list.List.Add(target); // 广播寻路路径 M2C_PathfindingResult m2CPathfindingResult = new M2C_PathfindingResult { Id = unit.Id, X = unitScene.X, Y = unitScene.Y, TX = target.x, TY = target.y, MoveSpeed = ConstDefine.MoveSpeed }; var brocast = unit.GetComponent(); brocast.Brocast(m2CPathfindingResult); bool ret = await unit.GetComponent().MoveToAsync(list.List, speed, cancellationToken); if (ret) // 如果返回false,说明被其它移动取消了,这时候不需要通知客户端stop { SendStop(unit,0); } } public static void Stop(this Unit unit) { unit.GetComponent().Stop(); SendStop(unit, 0); } private static void SendStop(Unit unit, int error) { if (!unit.IsTeamLeader) return; UnitScene unitScene = unit.GetComponent(); var brocast = unit.GetComponent(); brocast.Brocast(new M2C_Stop() { Error = error, Id = unit.Id, X = unitScene.X, Y = unitScene.Y, YAngle = unitScene.YAngle }); } } }