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; public static ETTask MoveTo(Unit unit, Vector2 target, ETCancellationToken token = null) { UnitScene unitScene = unit.GetComponent(); Vector2 pos = unitScene.Position; int yAngle = pos.x <= target.x? 0 : 180; return MoveTo(unit, target, yAngle); } public static async ETTask MoveTo(Unit unit, Vector2 target, int yAngle, ETCancellationToken token = null) { try { UnitScene unitScene = unit.GetComponent(); unitScene.targetPos = target; unitScene.isMoved = true; bool ret = await FindPathMoveToAsync(unit, target, token); unitScene.YAngle = yAngle; unitScene.isMoved = false; return ret; } catch (Exception e) { Log.Error(e); } return false; } // 可以多次调用,多次调用的话会取消上一次的协程 private static async ETTask FindPathMoveToAsync(this Unit unit, Vector3 target, ETCancellationToken cancellationToken = null) { float speed = ConstDefine.MoveSpeed; using ListComponent 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 }; BrocastComponent brocast = unit.GetComponent(); brocast.Brocast(m2CPathfindingResult); bool ret = await unit.GetComponent().MoveToAsync(list.List, speed, cancellationToken); if (ret) // 如果返回false,说明被其它移动取消了,这时候不需要通知客户端stop { SendStop(unit, 0); } return ret; } 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(); BrocastComponent brocast = unit.GetComponent(); brocast.Brocast(new M2C_Stop() { Error = error, Id = unit.Id, X = unitScene.X, Y = unitScene.Y, YAngle = unitScene.YAngle }); } public static async ETVoid TeamMoveTo(Team team, Vector2 target) { var list = team.GetUnits(); for (var curr = list.First; curr != null; curr = curr.Next) { Unit item = curr.Value; long unitInstanceId = item.InstanceId; await TimerComponent.Instance.WaitAsync(300); if (!item) continue; if (unitInstanceId != item.InstanceId) continue; UnitScene unitScene = item.GetComponent(); Vector2 delta = MoveHelper.CalucateDistanceXandY(unitScene.Position, target); int index = team.GetIndex(item.Id); Vector2 targetPos = new(target.x - delta.x * index, target.y - delta.y * index); MoveHelper.MoveTo(item, targetPos).Coroutine(); // 移动到目标点, 返回false表示协程取消 } } public static Vector2 CalucateDistanceXandY(Vector2 posA, Vector2 posB) { const float TeamDistanceBetweenUnits = 0.8f; 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)); } } }