using System; using UnityEngine; using UnityEngine.AI; namespace ET { public class PeopleViewComponentAwakeSystem : AwakeSystem { public override void Awake(PeopleViewComponent self) { self.Awake(); } } public class PeopleViewComponentDestroySystem : DestroySystem { public override void Destroy(PeopleViewComponent self) { self.Destroy(); } } [Timer(TimerType.SyncPeoplePosToServerTimer)] public class SyncPeoplePosToServerTimer : ATimer { public override void Run(PeopleViewComponent self) { try { if (self.IsDisposed || self.Parent == null) { return; } if (self.DomainScene() == null) { return; } self.SyncPosToServer().Coroutine(); } catch (Exception e) { Log.Error(e.ToString()); } } } public class PeopleViewComponentUpdateSystem : UpdateSystem { public override void Update(PeopleViewComponent self) { self.Update(); } } [FriendClass(typeof(PeopleViewComponent))] [FriendClass(typeof(MapComponent))] [FriendClass(typeof(People))] public static class PeopleViewComponentSystem { public static void Awake(this PeopleViewComponent self) { var people = self.GetParent(); self.CreatePeople(people); self.SyncPosTimer = TimerComponent.Instance.NewRepeatedTimer(1000, TimerType.SyncPeoplePosToServerTimer, self); } public static void CreatePeople(this PeopleViewComponent self, People peopleInfo) { self.People = peopleInfo; var mapComp = self.ZoneScene().CurrentScene().GetComponent(); GameObject peopleGO = self.InstantiateSync("People_1001", mapComp.PeopleRoot); self.PeopleRoot = peopleGO; // set up navMeshAgent self.Agent = peopleGO.AddComponent(); self.Agent.speed = 2; self.Agent.acceleration = 100; self.Agent.updateRotation = false; self.Agent.updateUpAxis = false; self.Agent.radius = 0.1f; Unit unit = UnitHelper.GetMyUnitFromZoneScene(self.ZoneScene()); peopleGO.transform.position = new Vector3(peopleInfo.PosX, peopleInfo.PosY, 0); self.Agent.destination = peopleGO.transform.position; } public static void Destroy(this PeopleViewComponent self) { if (self.IsDisposed || self.Parent == null) { return; } TimerComponent.Instance.Remove(ref self.SyncPosTimer); GameObject.Destroy(self.PeopleRoot); } public static void MoveToPos(this PeopleViewComponent self, Vector3 dest) { self.Agent.destination = dest; if (!self.IsMoving) { Game.EventSystem.Publish(new EventType.PeopleMoveStart() { People = self.People }); self.IsMoving = true; } } public static void SetNavEnable(this PeopleViewComponent self, bool enable) { self.Agent.enabled = enable; } public static void Stop(this PeopleViewComponent self) { if (!self.IsMoving) { return; } self.Agent.destination = self.PeopleRoot.transform.position; self.IsMoving = false; Game.EventSystem.Publish(new EventType.PeopleMoveEnd() { People = self.People }); } public static void Update(this PeopleViewComponent self) { if (self.IsMoving) { // 检查是否到达目标点 // https://answers.unity.com/questions/324589/how-can-i-tell-when-a-navmesh-has-reached-its-dest.html?childToView=746157#answer-746157 if (!self.Agent.pathPending) { if (self.Agent.remainingDistance <= self.Agent.stoppingDistance) { if (!self.Agent.hasPath || self.Agent.velocity.sqrMagnitude == 0f) { // Log.Info("Reach Dest"); self.Stop(); } } } } } public static async ETTask SyncPosToServer(this PeopleViewComponent self) { if (self.IsMoving) { Unit unit = UnitHelper.GetMyUnitFromZoneScene(self.ZoneScene()); Vector3 pos = self.PeopleRoot.transform.position; await PeopleHelper.Move(unit, self.People.Id, pos.x, pos.y); } await ETTask.CompletedTask; } } }