123 lines
4.4 KiB
C#
123 lines
4.4 KiB
C#
|
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<UnitScene>();
|
|||
|
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<UnitScene>().YAngle = yAngle;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
await TimerComponent.Instance.WaitAsync(300);
|
|||
|
UnitScene unitScene = u.GetComponent<UnitScene>();
|
|||
|
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<Vector3>.Create();
|
|||
|
UnitScene unitScene = unit.GetComponent<UnitScene>();
|
|||
|
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<BrocastComponent>();
|
|||
|
brocast.Brocast(m2CPathfindingResult);
|
|||
|
|
|||
|
|
|||
|
bool ret = await unit.GetComponent<MoveComponent>().MoveToAsync(list.List, speed, cancellationToken);
|
|||
|
if (ret) // 如果返回false,说明被其它移动取消了,这时候不需要通知客户端stop
|
|||
|
{
|
|||
|
SendStop(unit,0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void Stop(this Unit unit)
|
|||
|
{
|
|||
|
unit.GetComponent<MoveComponent>().Stop();
|
|||
|
SendStop(unit, 0);
|
|||
|
}
|
|||
|
private static void SendStop(Unit unit, int error)
|
|||
|
{
|
|||
|
if (!unit.IsTeamLeader) return;
|
|||
|
UnitScene unitScene = unit.GetComponent<UnitScene>();
|
|||
|
var brocast = unit.GetComponent<BrocastComponent>();
|
|||
|
brocast.Brocast(new M2C_Stop()
|
|||
|
{
|
|||
|
Error = error,
|
|||
|
Id = unit.Id,
|
|||
|
X = unitScene.X,
|
|||
|
Y = unitScene.Y,
|
|||
|
|
|||
|
YAngle = unitScene.YAngle
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|