You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
9.3 KiB
309 lines
9.3 KiB
using System; |
|
using System.Collections.Generic; |
|
using UnityEngine; |
|
|
|
namespace ET |
|
{ |
|
[Timer(TimerType.MoveTimer)] |
|
public class MoveTimer: ATimer<MoveComponent> |
|
{ |
|
public override void Run(MoveComponent self) |
|
{ |
|
try |
|
{ |
|
self.MoveForward(false); |
|
} |
|
catch (Exception e) |
|
{ |
|
Log.Error($"move timer error: {self.Id}\n{e}"); |
|
} |
|
} |
|
} |
|
|
|
[ObjectSystem] |
|
public class MoveComponentDestroySystem: DestroySystem<MoveComponent> |
|
{ |
|
public override void Destroy(MoveComponent self) |
|
{ |
|
self.Clear(); |
|
} |
|
} |
|
|
|
[ObjectSystem] |
|
public class MoveComponentAwakeSystem: AwakeSystem<MoveComponent> |
|
{ |
|
public override void Awake(MoveComponent self) |
|
{ |
|
self.StartTime = 0; |
|
self.StartPos = Vector3.zero; |
|
self.NeedTime = 0; |
|
self.MoveTimer = 0; |
|
self.Callback = null; |
|
self.Targets.Clear(); |
|
self.Speed = 0; |
|
self.N = 0; |
|
self.TurnTime = 0; |
|
} |
|
} |
|
|
|
[FriendClass(typeof(MoveComponent))] |
|
public static class MoveComponentSystem |
|
{ |
|
public static bool IsArrived(this MoveComponent self) |
|
{ |
|
return self.Targets.Count == 0; |
|
} |
|
|
|
public static bool ChangeSpeed(this MoveComponent self, float speed) |
|
{ |
|
if (self.IsArrived()) |
|
{ |
|
return false; |
|
} |
|
|
|
if (speed < 0.0001) |
|
{ |
|
return false; |
|
} |
|
|
|
Unit unit = self.GetParent<Unit>(); |
|
|
|
using (ListComponent<Vector3> path = ListComponent<Vector3>.Create()) |
|
{ |
|
self.MoveForward(true); |
|
|
|
// path.Add(unit.Position); // 第一个是Unit的pos |
|
for (int i = self.N; i < self.Targets.Count; ++i) |
|
{ |
|
path.Add(self.Targets[i]); |
|
} |
|
self.MoveToAsync(path, speed).Coroutine(); |
|
} |
|
return true; |
|
} |
|
|
|
public static async ETTask<bool> MoveToAsync(this MoveComponent self, List<Vector3> target, float speed, int turnTime = 100, ETCancellationToken cancellationToken = null) |
|
{ |
|
self.Stop(); |
|
|
|
foreach (Vector3 v in target) |
|
{ |
|
self.Targets.Add(v); |
|
} |
|
|
|
self.IsTurnHorizontal = true; |
|
self.TurnTime = turnTime; |
|
self.Speed = speed; |
|
ETTask<bool> tcs = ETTask<bool>.Create(true); |
|
self.Callback = (ret) => { tcs.SetResult(ret); }; |
|
|
|
Game.EventSystem.Publish(new EventType.MoveStart(){Unit = self.GetParent<Unit>()}); |
|
|
|
self.StartMove(); |
|
|
|
void CancelAction() |
|
{ |
|
self.Stop(); |
|
} |
|
|
|
bool moveRet; |
|
try |
|
{ |
|
cancellationToken?.Add(CancelAction); |
|
moveRet = await tcs; |
|
} |
|
finally |
|
{ |
|
cancellationToken?.Remove(CancelAction); |
|
} |
|
|
|
if (moveRet) |
|
{ |
|
Game.EventSystem.Publish(new EventType.MoveStop(){Unit = self.GetParent<Unit>()}); |
|
} |
|
return moveRet; |
|
} |
|
|
|
public static void MoveForward(this MoveComponent self, bool needCancel) |
|
{ |
|
// Unit unit = self.GetParent<Unit>(); |
|
// |
|
// long timeNow = TimeHelper.ClientNow(); |
|
// long moveTime = timeNow - self.StartTime; |
|
// |
|
// while (true) |
|
// { |
|
// if (moveTime <= 0) |
|
// { |
|
// return; |
|
// } |
|
// |
|
// // 计算位置插值 |
|
// if (moveTime >= self.NeedTime) |
|
// { |
|
// unit.Position = self.NextTarget; |
|
// if (self.TurnTime > 0) |
|
// { |
|
// unit.Rotation = self.To; |
|
// } |
|
// } |
|
// else |
|
// { |
|
// // 计算位置插值 |
|
// float amount = moveTime * 1f / self.NeedTime; |
|
// if (amount > 0) |
|
// { |
|
// Vector3 newPos = Vector3.Lerp(self.StartPos, self.NextTarget, amount); |
|
// unit.Position = newPos; |
|
// } |
|
// |
|
// // 计算方向插值 |
|
// if (self.TurnTime > 0) |
|
// { |
|
// amount = moveTime * 1f / self.TurnTime; |
|
// Quaternion q = Quaternion.Slerp(self.From, self.To, amount); |
|
// unit.Rotation = q; |
|
// } |
|
// } |
|
// |
|
// moveTime -= self.NeedTime; |
|
// |
|
// // 表示这个点还没走完,等下一帧再来 |
|
// if (moveTime < 0) |
|
// { |
|
// return; |
|
// } |
|
// |
|
// // 到这里说明这个点已经走完 |
|
// |
|
// // 如果是最后一个点 |
|
// if (self.N >= self.Targets.Count - 1) |
|
// { |
|
// unit.Position = self.NextTarget; |
|
// unit.Rotation = self.To; |
|
// |
|
// Action<bool> callback = self.Callback; |
|
// self.Callback = null; |
|
// |
|
// self.Clear(); |
|
// callback?.Invoke(!needCancel); |
|
// return; |
|
// } |
|
// |
|
// self.SetNextTarget(); |
|
// } |
|
} |
|
|
|
private static void StartMove(this MoveComponent self) |
|
{ |
|
Unit unit = self.GetParent<Unit>(); |
|
|
|
self.BeginTime = TimeHelper.ClientNow(); |
|
self.StartTime = self.BeginTime; |
|
self.SetNextTarget(); |
|
|
|
self.MoveTimer = TimerComponent.Instance.NewFrameTimer(TimerType.MoveTimer, self); |
|
} |
|
|
|
private static void SetNextTarget(this MoveComponent self) |
|
{ |
|
|
|
// Unit unit = self.GetParent<Unit>(); |
|
// |
|
// ++self.N; |
|
// |
|
// // 时间计算用服务端的位置, 但是移动要用客户端的位置来插值 |
|
// Vector3 v = self.GetFaceV(); |
|
// float distance = v.magnitude; |
|
// |
|
// // 插值的起始点要以unit的真实位置来算 |
|
// self.StartPos = unit.Position; |
|
// |
|
// self.StartTime += self.NeedTime; |
|
// |
|
// self.NeedTime = (long) (distance / self.Speed * 1000); |
|
// |
|
// |
|
// if (self.TurnTime > 0) |
|
// { |
|
// // 要用unit的位置 |
|
// Vector3 faceV = self.GetFaceV(); |
|
// if (faceV.sqrMagnitude < 0.0001f) |
|
// { |
|
// return; |
|
// } |
|
// self.From = unit.Rotation; |
|
// |
|
// if (self.IsTurnHorizontal) |
|
// { |
|
// faceV.y = 0; |
|
// } |
|
// |
|
// if (Math.Abs(faceV.x) > 0.01 || Math.Abs(faceV.z) > 0.01) |
|
// { |
|
// self.To = Quaternion.LookRotation(faceV, Vector3.up); |
|
// } |
|
// |
|
// return; |
|
// } |
|
// |
|
// if (self.TurnTime == 0) // turn time == 0 立即转向 |
|
// { |
|
// Vector3 faceV = self.GetFaceV(); |
|
// if (self.IsTurnHorizontal) |
|
// { |
|
// faceV.y = 0; |
|
// } |
|
// |
|
// if (Math.Abs(faceV.x) > 0.01 || Math.Abs(faceV.z) > 0.01) |
|
// { |
|
// self.To = Quaternion.LookRotation(faceV, Vector3.up); |
|
// unit.Rotation = self.To; |
|
// } |
|
// } |
|
} |
|
|
|
private static Vector3 GetFaceV(this MoveComponent self) |
|
{ |
|
return self.NextTarget - self.PreTarget; |
|
} |
|
|
|
public static bool FlashTo(this MoveComponent self, Vector3 target) |
|
{ |
|
// Unit unit = self.GetParent<Unit>(); |
|
// unit.Position = target; |
|
return true; |
|
} |
|
|
|
public static void Stop(this MoveComponent self) |
|
{ |
|
if (self.Targets.Count > 0) |
|
{ |
|
self.MoveForward(true); |
|
} |
|
|
|
self.Clear(); |
|
} |
|
|
|
public static void Clear(this MoveComponent self) |
|
{ |
|
self.StartTime = 0; |
|
self.StartPos = Vector3.zero; |
|
self.BeginTime = 0; |
|
self.NeedTime = 0; |
|
TimerComponent.Instance?.Remove(ref self.MoveTimer); |
|
self.Targets.Clear(); |
|
self.Speed = 0; |
|
self.N = 0; |
|
self.TurnTime = 0; |
|
self.IsTurnHorizontal = false; |
|
|
|
if (self.Callback != null) |
|
{ |
|
Action<bool> callback = self.Callback; |
|
self.Callback = null; |
|
callback.Invoke(false); |
|
} |
|
} |
|
} |
|
} |