Browse Source

简化了移动逻辑实现

tanghai 7 năm trước cách đây
mục cha
commit
e7ac247aa6

+ 29 - 24
Server/Model/Module/Demo/MoveComponent.cs

@@ -1,5 +1,5 @@
+using System;
 using System.Threading;
-using System.Threading.Tasks;
 using PF;
 
 namespace ETModel
@@ -11,59 +11,64 @@ namespace ETModel
         // 开启移动协程的时间
         public long StartTime;
 
-        public long lastFrameTime;
-
         // 开启移动协程的Unit的位置
         public Vector3 StartPos;
 
-        // 移动的方向标准化
-        public Vector3 DirNormalized;
+        public long needTime;
 
         // 当前的移动速度
         public float Speed = 5;
-
-        public void Awake()
-        {
-            this.Target = this.GetParent<Unit>().Position;
-        }
         
         // 开启协程移动,每100毫秒移动一次,并且协程取消的时候会计算玩家真实移动
         // 比方说玩家移动了2500毫秒,玩家有新的目标,这时旧的移动协程结束,将计算250毫秒移动的位置,而不是300毫秒移动的位置
-        public async Task StartMove(CancellationToken cancellationToken)
+        public async ETTask StartMove(CancellationToken cancellationToken)
         {
             Unit unit = this.GetParent<Unit>();
             this.StartPos = unit.Position;
             this.StartTime = TimeHelper.Now();
-            this.DirNormalized = (this.Target - unit.Position).normalized;
+            float distance = (this.Target - this.StartPos).magnitude;
+            if (Math.Abs(distance) < 0.1f)
+            {
+                return;
+            }
+            
+            this.needTime = (long)(distance / this.Speed * 1000);
             
             TimerComponent timerComponent = Game.Scene.GetComponent<TimerComponent>();
             
             // 协程如果取消,将算出玩家的真实位置,赋值给玩家
             cancellationToken.Register(() =>
             {
-                // 算出当前玩家的位置
                 long timeNow = TimeHelper.Now();
-                unit.Position = StartPos + this.DirNormalized * this.Speed * (timeNow - this.StartTime) / 1000f;
+                if (timeNow - this.StartTime >= this.needTime)
+                {
+                    unit.Position = this.Target;
+                }
+                else
+                {
+                    float amount = (timeNow - this.StartTime) * 1f / this.needTime;
+                    unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount);
+                }
             });
-            
+
             while (true)
             {
-                Vector3 willPos = unit.Position + this.DirNormalized * this.Speed * 0.05f;
-                if ((willPos - this.StartPos).magnitude > (this.Target - this.StartPos).magnitude - 0.1f)
+                await timerComponent.WaitAsync(50, cancellationToken);
+                
+                long timeNow = TimeHelper.Now();
+                
+                if (timeNow - this.StartTime >= this.needTime)
                 {
                     unit.Position = this.Target;
                     break;
                 }
-                
-                await timerComponent.WaitAsync(50, cancellationToken);
-                
-                long timeNow = TimeHelper.Now();
-                lastFrameTime = timeNow;
-                unit.Position = StartPos + this.DirNormalized * this.Speed * (timeNow - this.StartTime) / 1000f;
+
+                float amount = (timeNow - this.StartTime) * 1f / this.needTime;
+                unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount);
             }
         }
         
-        public async Task MoveToAsync(Vector3 target, CancellationToken cancellationToken)
+        public async ETTask MoveToAsync(Vector3 target, CancellationToken cancellationToken)
         {
             // 新目标点离旧目标点太近,不设置新的
             if ((target - this.Target).sqrMagnitude < 0.01f)

+ 2 - 0
Unity/Assets/Hotfix/Module/Demo/M2C_PathfindingResultHandler.cs

@@ -10,6 +10,8 @@ namespace ETHotfix
 		{
 			Unit unit = ETModel.Game.Scene.GetComponent<UnitComponent>().Get(message.Id);
 			
+			
+			unit.GetComponent<AnimatorComponent>().SetFloatValue("Speed", 5f);
 			UnitPathComponent unitPathComponent = unit.GetComponent<UnitPathComponent>();
 
 			unitPathComponent.StartMove(message).NoAwait();

+ 41 - 188
Unity/Assets/Model/Module/Demo/MoveComponent.cs

@@ -1,18 +1,9 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System;
+using System.Threading;
 using UnityEngine;
 
 namespace ETModel
 {
-	[ObjectSystem]
-	public class MoveComponentAwakeSystem : AwakeSystem<MoveComponent>
-	{
-		public override void Awake(MoveComponent self)
-		{
-			self.Awake();
-		}
-	}
-
 	[ObjectSystem]
 	public class MoveComponentUpdateSystem : UpdateSystem<MoveComponent>
 	{
@@ -24,212 +15,74 @@ namespace ETModel
 
 	public class MoveComponent : Component
 	{
-		private AnimatorComponent animatorComponent;
+		public Vector3 Target;
 
-		public long mainSpeed;
-		public Vector3 speed;
+		// 开启移动协程的时间
+		public long StartTime;
 
-		// turn
-		public Quaternion To;
-		public Quaternion From;
-		public float t = float.MaxValue;
-		public float TurnTime = 0.1f;
+		// 开启移动协程的Unit的位置
+		public Vector3 StartPos;
 
-		public bool IsArrived { get; private set; } = true;
+		public long needTime;
 
-		public Vector3 Dest;
+		// 当前的移动速度
+		public float Speed = 5;
+		
+		public ETTaskCompletionSource moveTcs;
 
-		public ETTaskCompletionSource<bool> moveTcs;
-
-		public Vector3 Speed
-		{
-			get
-			{
-				return speed;
-			}
-			set
-			{
-				speed = value;
-				animatorComponent?.SetFloatValue("Speed", speed.magnitude);
-			}
-		}
-
-		public void Awake()
-		{
-			this.animatorComponent = this.Entity.GetComponent<AnimatorComponent>();
-		}
 
 		public void Update()
 		{
-			UpdateTurn();
-
-			if (this.IsArrived)
-			{
-				return;
-			}
-
-			if (this.Speed.sqrMagnitude < 0.01f)
+			if (this.moveTcs == null)
 			{
 				return;
 			}
-
-			Unit unit = this.GetParent<Unit>();
-			Vector3 moveVector3 = this.Speed * Time.deltaTime;
 			
-			float dist = (this.Dest - unit.Position).magnitude;
-			if (moveVector3.magnitude >= dist || dist < 0.1f)
-			{
-				unit.Position = this.Dest;
-				this.IsArrived = true;
-				this.moveTcs?.SetResult(true);
-				return;
-			}
-
-			unit.Position = unit.Position + moveVector3;
-		}
+			Unit unit = this.GetParent<Unit>();
+			long timeNow = TimeHelper.Now();
 
-		private void UpdateTurn()
-		{
-			//Log.Debug($"update turn: {this.t} {this.TurnTime}");
-			if (this.t > this.TurnTime)
+			if (timeNow - this.StartTime >= this.needTime)
 			{
+				unit.Position = this.Target;
+				ETTaskCompletionSource tcs = this.moveTcs;
+				this.moveTcs = null;
+				tcs.SetResult();
 				return;
 			}
 
-			this.t += Time.deltaTime;
-
-			Quaternion v = Quaternion.Slerp(this.From, this.To, this.t / this.TurnTime);
-			this.GetParent<Unit>().Rotation = v;
+			float amount = (timeNow - this.StartTime) * 1f / this.needTime;
+			unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount);
 		}
 
-		public void MoveTo(Vector3 dest, float speedValue)
+		public ETTask MoveToAsync(Vector3 target, float speedValue, CancellationToken cancellationToken)
 		{
-			if ((dest - this.GetParent<Unit>().Position).magnitude < 0.1f)
-			{
-				this.IsArrived = true;
-				return;
-			}
+			Unit unit = this.GetParent<Unit>();
 			
-			if ((dest - this.Dest).magnitude < 0.1f)
+			if ((target - this.Target).magnitude < 0.1f)
 			{
-				return;
+				return ETTask.CompletedTask;
 			}
 			
-			this.IsArrived = false;
-			Vector3 spd = dest - this.GetParent<Unit>().Position;
-			spd = spd.normalized * speedValue;
-			this.Speed = spd;
-			this.Dest = dest;
-		}
-
-		public ETTask<bool> MoveToAsync(Vector3 dest, float speedValue, CancellationToken cancellationToken)
-		{
-			if ((dest - this.GetParent<Unit>().Position).magnitude < 0.1f)
-			{
-				this.IsArrived = true;
-				return ETTask.FromResult(false);
-			}
+			this.Target = target;
 
-			if ((dest - this.Dest).magnitude < 0.1f)
-			{
-				return ETTask.FromResult(false);
-			}
 			
-			this.moveTcs = new ETTaskCompletionSource<bool>();
-			this.IsArrived = false;
-			Vector3 spd = dest - this.GetParent<Unit>().Position;
-			spd = spd.normalized * speedValue;
-			this.Speed = spd;
-			this.Dest = dest;
-
-			cancellationToken.Register(() => this.moveTcs = null);
-
-			return this.moveTcs.Task;
-		}
-
-		/// <summary>
-		/// 停止移动Unit,只停止地面正常移动,不停止击飞等移动
-		/// </summary>
-		public void Stop()
-		{
-			this.speed = Vector3.zero;
-			this.animatorComponent?.SetFloatValue("Speed", 0);
-		}
-
-		/// <summary>
-		/// 改变Unit的朝向
-		/// </summary>
-		public void Turn2D(Vector3 dir, float turnTime = 0.1f)
-		{
-			Vector3 nexpos = this.GetParent<Unit>().GameObject.transform.position + dir;
-			Turn(nexpos, turnTime);
-		}
-
-		/// <summary>
-		/// 改变Unit的朝向
-		/// </summary>
-		public void Turn(Vector3 target, float turnTime = 0.1f)
-		{
-			Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetParent<Unit>().Position, target);
-
-			this.To = quaternion;
-			this.From = this.GetParent<Unit>().Rotation;
-			this.t = 0;
-			this.TurnTime = turnTime;
-		}
-
-		/// <summary>
-		/// 改变Unit的朝向
-		/// </summary>
-		/// <param name="angle">与X轴正方向的夹角</param>
-		public void Turn(float angle, float turnTime = 0.1f)
-		{
-			Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);
-
-			this.To = quaternion;
-			this.From = this.GetParent<Unit>().Rotation;
-			this.t = 0;
-			this.TurnTime = turnTime;
-		}
-
-		public void Turn(Quaternion quaternion, float turnTime = 0.1f)
-		{
-			this.To = quaternion;
-			this.From = this.GetParent<Unit>().Rotation;
-			this.t = 0;
-			this.TurnTime = turnTime;
-		}
-
-		public void TurnImmediately(Quaternion quaternion)
-		{
-			this.GetParent<Unit>().Rotation = quaternion;
-		}
-
-		public void TurnImmediately(Vector3 target)
-		{
-			Vector3 nowPos = this.GetParent<Unit>().Position;
-			if (nowPos == target)
+			this.StartPos = unit.Position;
+			this.StartTime = TimeHelper.Now();
+			float distance = (this.Target - this.StartPos).magnitude;
+			if (Math.Abs(distance) < 0.1f)
 			{
-				return;
+				return ETTask.CompletedTask;
 			}
-
-			Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetParent<Unit>().Position, target);
-			this.GetParent<Unit>().Rotation = quaternion;
-		}
-
-		public void TurnImmediately(float angle)
-		{
-			Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);
-			this.GetParent<Unit>().Rotation = quaternion;
-		}
-
-		public override void Dispose()
-		{
-			if (this.IsDisposed)
+            
+			this.needTime = (long)(distance / this.Speed * 1000);
+			
+			this.moveTcs = new ETTaskCompletionSource();
+			
+			cancellationToken.Register(() =>
 			{
-				return;
-			}
-			base.Dispose();
+				this.moveTcs = null;
+			});
+			return this.moveTcs.Task;
 		}
 	}
 }

+ 117 - 0
Unity/Assets/Model/Module/Demo/TurnComponent.cs

@@ -0,0 +1,117 @@
+using UnityEngine;
+
+namespace ETModel
+{
+	[ObjectSystem]
+	public class TurnComponentUpdateSystem : UpdateSystem<TurnComponent>
+	{
+		public override void Update(TurnComponent self)
+		{
+			self.Update();
+		}
+	}
+
+	public class TurnComponent : Component
+	{
+		// turn
+		public Quaternion To;
+		public Quaternion From;
+		public float t = float.MaxValue;
+		public float TurnTime = 0.1f;
+
+		public void Update()
+		{
+			UpdateTurn();
+		}
+
+		private void UpdateTurn()
+		{
+			//Log.Debug($"update turn: {this.t} {this.TurnTime}");
+			if (this.t > this.TurnTime)
+			{
+				return;
+			}
+
+			this.t += Time.deltaTime;
+
+			Quaternion v = Quaternion.Slerp(this.From, this.To, this.t / this.TurnTime);
+			this.GetParent<Unit>().Rotation = v;
+		}
+
+		/// <summary>
+		/// 改变Unit的朝向
+		/// </summary>
+		public void Turn2D(Vector3 dir, float turnTime = 0.1f)
+		{
+			Vector3 nexpos = this.GetParent<Unit>().GameObject.transform.position + dir;
+			Turn(nexpos, turnTime);
+		}
+
+		/// <summary>
+		/// 改变Unit的朝向
+		/// </summary>
+		public void Turn(Vector3 target, float turnTime = 0.1f)
+		{
+			Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetParent<Unit>().Position, target);
+
+			this.To = quaternion;
+			this.From = this.GetParent<Unit>().Rotation;
+			this.t = 0;
+			this.TurnTime = turnTime;
+		}
+
+		/// <summary>
+		/// 改变Unit的朝向
+		/// </summary>
+		/// <param name="angle">与X轴正方向的夹角</param>
+		public void Turn(float angle, float turnTime = 0.1f)
+		{
+			Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);
+
+			this.To = quaternion;
+			this.From = this.GetParent<Unit>().Rotation;
+			this.t = 0;
+			this.TurnTime = turnTime;
+		}
+
+		public void Turn(Quaternion quaternion, float turnTime = 0.1f)
+		{
+			this.To = quaternion;
+			this.From = this.GetParent<Unit>().Rotation;
+			this.t = 0;
+			this.TurnTime = turnTime;
+		}
+
+		public void TurnImmediately(Quaternion quaternion)
+		{
+			this.GetParent<Unit>().Rotation = quaternion;
+		}
+
+		public void TurnImmediately(Vector3 target)
+		{
+			Vector3 nowPos = this.GetParent<Unit>().Position;
+			if (nowPos == target)
+			{
+				return;
+			}
+
+			Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetParent<Unit>().Position, target);
+			this.GetParent<Unit>().Rotation = quaternion;
+		}
+
+		public void TurnImmediately(float angle)
+		{
+			Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);
+			this.GetParent<Unit>().Rotation = quaternion;
+		}
+
+		public override void Dispose()
+		{
+			if (this.IsDisposed)
+			{
+				return;
+			}
+			base.Dispose();
+		}
+	}
+}

+ 11 - 0
Unity/Assets/Model/Module/Demo/TurnComponent.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 216094475ea0a054fa9aba89cf35ff5c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 0
Unity/Assets/Model/Module/Demo/UnitFactory.cs

@@ -18,6 +18,7 @@ namespace ETModel
 	        unit.GameObject.transform.SetParent(parent.transform, false);
 			unit.AddComponent<AnimatorComponent>();
 	        unit.AddComponent<MoveComponent>();
+	        unit.AddComponent<TurnComponent>();
 	        unit.AddComponent<UnitPathComponent>();
 
             unitComponent.Add(unit);

+ 2 - 4
Unity/Assets/Model/Module/Demo/UnitPathComponent.cs

@@ -1,6 +1,5 @@
 using System.Collections.Generic;
 using System.Threading;
-using System.Threading.Tasks;
 using UnityEngine;
 
 namespace ETModel
@@ -13,7 +12,7 @@ namespace ETModel
 
 		public CancellationTokenSource CancellationTokenSource;
 		
-		public async Task StartMove(CancellationToken cancellationToken)
+		public async ETTask StartMove(CancellationToken cancellationToken)
 		{
 			for (int i = 0; i < this.Path.Count; ++i)
 			{
@@ -33,8 +32,7 @@ namespace ETModel
 					}
 				}
 
-				MoveComponent moveComponent = this.Entity.GetComponent<MoveComponent>();
-				moveComponent.Turn(v);
+				this.Entity.GetComponent<TurnComponent>().Turn(v);
 				await this.Entity.GetComponent<MoveComponent>().MoveToAsync(v, speed, cancellationToken);
 			}
 		}

+ 1 - 0
Unity/Unity.Model.csproj

@@ -295,6 +295,7 @@
     <Compile Include="Assets\Model\Module\Demo\PlayerComponent.cs" />
     <Compile Include="Assets\Model\Module\Demo\PlayerFactory.cs" />
     <Compile Include="Assets\Model\Module\Demo\SessionComponent.cs" />
+    <Compile Include="Assets\Model\Module\Demo\TurnComponent.cs" />
     <Compile Include="Assets\Model\Module\Demo\Unit.cs" />
     <Compile Include="Assets\Model\Module\Demo\UnitComponent.cs" />
     <Compile Include="Assets\Model\Module\Demo\UnitFactory.cs" />