122 lines
4.5 KiB
C#
122 lines
4.5 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;
|
||
|
||
public static ETTask<bool> MoveTo(Unit unit, Vector2 target, ETCancellationToken token = null)
|
||
{
|
||
UnitScene unitScene = unit.GetComponent<UnitScene>();
|
||
Vector2 pos = unitScene.Position;
|
||
int yAngle = pos.x <= target.x? 0 : 180;
|
||
return MoveTo(unit, target, yAngle);
|
||
}
|
||
|
||
public static async ETTask<bool> MoveTo(Unit unit, Vector2 target, int yAngle, ETCancellationToken token = null)
|
||
{
|
||
try
|
||
{
|
||
UnitScene unitScene = unit.GetComponent<UnitScene>();
|
||
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<bool> FindPathMoveToAsync(this Unit unit, Vector3 target, ETCancellationToken cancellationToken = null)
|
||
{
|
||
float speed = ConstDefine.MoveSpeed;
|
||
|
||
using ListComponent<Vector3> 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
|
||
};
|
||
BrocastComponent 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);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
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>();
|
||
BrocastComponent brocast = unit.GetComponent<BrocastComponent>();
|
||
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<UnitScene>();
|
||
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));
|
||
}
|
||
}
|
||
} |