Przeglądaj źródła

增加战斗单位逻辑

大爷 2 lat temu
rodzic
commit
58cd0fbea3
32 zmienionych plików z 903 dodań i 291 usunięć
  1. 19 0
      Unity/Assets/Scripts/Codes/Hotfix/Client/EntryEvent2_InitClient.cs
  2. 11 0
      Unity/Assets/Scripts/Codes/Hotfix/Client/EntryEvent2_InitClient.cs.meta
  3. 298 281
      Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattleMgr.cs
  4. 1 1
      Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattlePushHandler.cs
  5. 53 0
      Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattleUnitFactory.cs
  6. 11 0
      Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattleUnitFactory.cs.meta
  7. 40 0
      Unity/Assets/Scripts/Codes/Hotfix/Client/battle/UnitListComponentSystem.cs
  8. 11 0
      Unity/Assets/Scripts/Codes/Hotfix/Client/battle/UnitListComponentSystem.cs.meta
  9. 1 7
      Unity/Assets/Scripts/Codes/HotfixView/Client/EntryEvent3_InitClient.cs
  10. 4 2
      Unity/Assets/Scripts/Codes/HotfixView/Client/Scene/AfterCreateCurrentScene_AddComponent.cs
  11. 29 0
      Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnDestroyZoneObject.cs
  12. 11 0
      Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnDestroyZoneObject.cs.meta
  13. 45 0
      Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnNewZoneObject.cs
  14. 11 0
      Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnNewZoneObject.cs.meta
  15. 8 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle.meta
  16. 8 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit.meta
  17. 45 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleActor.cs
  18. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleActor.cs.meta
  19. 9 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleMonster.cs
  20. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleMonster.cs.meta
  21. 48 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleObject.cs
  22. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleObject.cs.meta
  23. 9 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattlePlayer.cs
  24. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattlePlayer.cs.meta
  25. 5 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleSpell.cs
  26. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleSpell.cs.meta
  27. 110 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleUnit.cs
  28. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleUnit.cs.meta
  29. 13 0
      Unity/Assets/Scripts/Codes/Model/Client/EventTypeClient.cs
  30. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/EventTypeClient.cs.meta
  31. 15 0
      Unity/Assets/Scripts/Codes/Model/Client/Unit/UnitListComponent.cs
  32. 11 0
      Unity/Assets/Scripts/Codes/Model/Client/Unit/UnitListComponent.cs.meta

+ 19 - 0
Unity/Assets/Scripts/Codes/Hotfix/Client/EntryEvent2_InitClient.cs

@@ -0,0 +1,19 @@
+namespace ET.Client
+{
+    [Event(SceneType.Process)]
+    public class EntryEvent2_InitClient : AEvent<ET.EventType.EntryEvent2>
+    {
+        protected override async ETTask Run(Scene scene, ET.EventType.EntryEvent2 args)
+        {
+            //加载战斗相关资源
+            Game.AddSingleton<BattleResourceMgr>();
+            await BattleResourceMgr.Instance.InitAsync();
+
+            Game.AddSingleton<BattleMgr>();
+            await BattleMgr.Instance.InitAsync();
+
+            Game.AddSingleton<BattleUnitFactory>();
+            await BattleUnitFactory.Instance.InitAsync();
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Hotfix/Client/EntryEvent2_InitClient.cs.meta

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

+ 298 - 281
Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattleMgr.cs

@@ -2,33 +2,30 @@
 using CommonAI.ZoneClient;
 using CommonLang;
 using ET.Client;
-using Microsoft.Cci;
-using System;
-using System.Collections.Generic;
-using System.Data;
 using System.IO;
-using System.Net;
-using System.Runtime.InteropServices.ComTypes;
-using XmdsCommon.Message;
 
 namespace ET
 {
+    [FriendOf(typeof(UnitListComponent))]
     public class BattleMgr : Singleton<BattleMgr>, ISingletonUpdate, ILayerClient
     {
         private bool isInited = false;
         public ZoneLayer Layer;
         private readonly MemoryStream writeBuffer = new MemoryStream(2048);
+        private EventDispatcher eventDispather;
 
         public async ETTask InitAsync()
         {
+            eventDispather = new EventDispatcher();
+            registerEventHandler();
             Layer = TemplateManager.Factory.CreateClientZoneLayer(BattleResourceMgr.Instance.GameEditorTemplates, this);
+            Layer.ActorSyncMode = SyncMode.ForceByServer;
 
-            Layer.LayerInit += OnLayerInit;
-            Layer.ObjectEnter += OnObjectEnter;
-            Layer.ObjectLeave += OnObjectLeave;
-            Layer.PlayerLeave += RemovePlayerInfo;
-            //Layer.MessageReceived += xxLayer_MessageReceived;
-            Layer.DecorationChanged += Layer_DecorationChanged;
+            Layer.LayerInit += LayerEvent_Init;
+            Layer.ObjectEnter += LayerEvent_ObjectEnter;
+            Layer.ObjectLeave += LayerEvent_ObjectLeave;
+            Layer.MessageReceived += LayerEvent_MessageReceived;
+            Layer.DecorationChanged += LayerEvent_DecorationChanged;
             isInited = true;
 
             await ETTask.CompletedTask;
@@ -42,12 +39,14 @@ namespace ET
             Layer.Update();
         }
 
+        //ILayerClient接口实现,供layer层调用
+        //layer层在收到LockActorEvent消息后调用
         void ILayerClient.BattleReady(bool bok)
         {
-            Log.Debug("battle ready.......");
-            //throw new System.NotImplementedException();
+            Log.Debug($"battle ready......{bok}");
         }
 
+        //ILayerClient接口实现,供layer层调用
         //layer层中需要发送消息到战斗服
         public void SendAction(CommonAI.Zone.Action action)
         {
@@ -56,338 +55,356 @@ namespace ET
                 Log.Error("playerComponent is null");
                 return;
             }
+            Log.Debug($">>>Send BattleMsg: {action.GetType()}");
 
             writeBuffer.Position = 0;
             if (BattleResourceMgr.Instance.BattleMsgDecoder.doEncode(writeBuffer, action))
             {
-                var param = new BattleEventPushToServer() { data = writeBuffer.ToArray() };
-                PlayerComponent.Instance.ClientScene().GetComponent<SessionComponent>().Session.Send(param);
+                PlayerComponent.Instance.ClientScene().GetComponent<SessionComponent>().Session.Send(new BattleEventPushToServer() { data = writeBuffer.ToArray() });
             }
         }
 
         //客户端自己模拟创建消息,发送到zonelayer层处理
-        public void PostMsg2Layer(IMessage msg)
+        public void PostMsg2Layer(CommonLang.Protocol.IMessage msg)
         {
         }
 
-        protected void OnLayerInit(CommonAI.ZoneClient.ZoneLayer layer)
+        //layer层在处理好战斗服推送的ClientEnterScene消息后回调
+        protected void LayerEvent_Init(CommonAI.ZoneClient.ZoneLayer layer)
         {
-            Log.Debug("OnLayerInit");
+            Log.Debug($"OnLayerInit- scene template ID:{layer.Data.ID}");
+
         }
 
         //单位进入战斗  
-        protected void OnObjectEnter(ZoneLayer layer, ZoneObject obj)
+        protected void LayerEvent_ObjectEnter(ZoneLayer layer, ZoneObject obj)
         {
             Log.Debug($"OnObjectEnter: {obj.Name}");
+
+            var unit = BattleUnitFactory.Instance.Create(obj);
+            if(unit != null )
+            {
+                if(unit is BattleActor)
+                {
+                    UnitListComponent.Instance.Actor = unit as BattleActor;
+                }
+                UnitListComponent.Instance.UnitList.Add(obj.ObjectID, unit);
+                unit.OnAwake(obj);
+            }
+            else
+            {
+                Log.Error($"unknow object enter:{obj.Name} ID:{obj.ObjectID}");
+            }
         }
 
         //单位离开战斗   
-        protected void OnObjectLeave(ZoneLayer layer, ZoneObject obj)
+        protected void LayerEvent_ObjectLeave(ZoneLayer layer, ZoneObject obj)
         {
             Log.Debug($"OnObjectLeave: {obj.Name}");
-        }
-        public void RemovePlayerInfo(ZoneLayer layer, ZoneObject obj)
-        {
-            Log.Debug($"RemovePlayerInfo: {obj.Name}");
-            /*ComAICell cell = null;
-            if (allUnits.TryGetValue(obj.ObjectID, out cell))
+
+            var unit = UnitListComponent.Instance.UnitList.Get(obj.ObjectID);
+            if(unit == null)
             {
-                if (!(cell is ComAIPlayer)) return;
-                var player = cell as ComAIPlayer;
-                var info = player.GetVirtual().GetBaseInfo();
-                if (info == null || string.IsNullOrEmpty(info.uuid) || !allPlayers.ContainsKey(info.uuid)) return;
-                grassStealth.DelPlayer(player);
-                allPlayers.Remove(info.uuid);
-                if (UnitLoadOkCallBack.ContainsKey(info.uuid)) UnitLoadOkCallBack.Remove(info.uuid);
-            }*/
+                Log.Error($"LayerEvent_ObjectLeave not exist:{obj.Name}:{obj.ObjectID}");
+                return;
+            }
+
+            unit.OnSleep();
+            UnitListComponent.Instance.UnitList.Remove(obj.ObjectID);
         }
 
-        protected void Layer_DecorationChanged(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneEditorDecoration ed)
+        protected void LayerEvent_DecorationChanged(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneEditorDecoration ed)
         {
-            Log.Debug("Layer_DecorationChanged");
+            Log.Error("Layer_DecorationChanged");
             /*DataMgr.Instance.RegionManager.OnDecorationChanged(ed);
             if (mDecoMgr != null)
             {
                 mDecoMgr.OnStateChange(ed);
             }*/
         }
-        /*private void OnEventHandler(CommonAI.Zone.Event e)
-{
-   if (e is SyncPosEvent || e is Pong)
-   {
-       return;
-   }
 
-   if (e is ChatEvent)
-   {
-       var evt = (e as ChatEvent);
-       var msg = evt.Message;
-       var evt_param = msg.Split('|');
-       if (evt_param.Length >= 2 && evt_param[0] == "Notice.Msg")
-       {
-           var dic = GameUtil.GetDBData("NoticeMsg", int.Parse(evt_param[1]));
-           if (dic != null)
+        protected void LayerEvent_MessageReceived(CommonAI.ZoneClient.ZoneLayer layer, CommonLang.Protocol.IMessage msg)
+        {
+            if (!(msg is CommonAI.Zone.Event) || msg is SyncPosEvent || msg is Pong)
+            {
+                return;
+            }
+            eventDispather.Notfify(msg as ObjectEvent);
+        }
+
+        private void registerEventHandler()
+        {
+            /*var e = msg as CommonAI.Zone.Event;
+           if (e is ChatEvent)
+           {
+               var evt = (e as ChatEvent);
+               var message = evt.Message;
+               var evt_param = message.Split('|');
+               if (evt_param.Length >= 2 && evt_param[0] == "Notice.Msg")
+               {
+                   var dic = GameUtil.GetDBData("NoticeMsg", int.Parse(evt_param[1]));
+                   if (dic != null)
+                   {
+                       string result = "";
+                       if (evt_param.Length >= 3 && evt_param[2] != null)
+                       {
+                           //根据参数个数 依次填值
+                           string[] par = evt_param[2].Split('.');
+                           if (par != null && par.Length > 0)
+                           {
+                               switch (par.Length)
+                               {
+                                   case 1:
+                                       {
+                                           result = Average(dic["MsgContent"] as string, par[0]);
+                                           break;
+                                       }
+                                   case 2:
+                                       {
+                                           result = Average(dic["MsgContent"] as string, par[0], par[1]);
+                                           break;
+                                       }
+                                   case 3:
+                                       {
+                                           result = Average(dic["MsgContent"] as string, par[0], par[1], par[2]);
+                                           break;
+                                       }
+                                   case 4:
+                                       {
+                                           result = Average(dic["MsgContent"] as string, par[0], par[1], par[2], par[3]);
+                                           break;
+                                       }
+                                   case 5:
+                                       {
+                                           result = Average(dic["MsgContent"] as string, par[0], par[1], par[2], par[3], par[4]);
+                                           break;
+                                       }
+                               }
+                           }
+                       }
+                       else
+                       {
+                           //没有参数
+                           result = (dic["MsgContent"] as string);
+                       }
+                       //
+                       EventManager.Fire("Event.OnEventHandler.star", new Dictionary<string, string>() {
+                       {"content", result}, {"keepTime", "" + (evt.KeepTimeMS/1000)}, {"content_is_text", "true"}
+                   });
+                   }
+                   else
+                   {
+                       YXJDebug.logError("config not exist >" + msg);
+                   }
+               }
+               else if (evt_param.Length == 2)
+               {
+                   string funcName = "GlobalHooks." + evt_param[0];
+                   object[] param = evt_param[1].Split(',');
+                   //Client.GetMainState().GetFunction(funcName).LazyCall(param);
+                   if (param.Length == 0)
+                       Client.GetMainState().Call(funcName, Client.LogMiss);
+                   else if (param.Length == 1)
+                       Client.GetMainState().Call(funcName, param[0], Client.LogMiss);
+                   else if (param.Length == 2)
+                       Client.GetMainState().Call(funcName, param[0], param[1], Client.LogMiss);
+                   else if (param.Length == 3)
+                       Client.GetMainState().Call(funcName, param[0], param[1], param[2], Client.LogMiss);
+                   else if (param.Length == 4)
+                       Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], Client.LogMiss);
+                   else if (param.Length == 5)
+                       Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], param[4], Client.LogMiss);
+                   else
+                   {
+                       YXJDebug.logError("BattleClientBase.OnEventHandler Error!funcName is {0}", funcName);
+                   }
+               }
+               else
+               {
+                   //位面进入退出效果
+                   if (msg == "EnterAOI")
+                   {
+                       var wwe = Camera.main.GetComponent<WaterWaveEffect>();
+                       if (wwe != null)
+                       {
+                           wwe.SetParam(40, -30, 3, 2);
+                           wwe.play();
+                       }
+                       //GameAlertManager.Instance.setAutoAnimiVisible(false);
+                       InAOI = true;
+                   }
+                   else if (msg == "LeaveAOI")
+                   {
+                       var wwe = Camera.main.GetComponent<WaterWaveEffect>();
+                       if (wwe != null)
+                       {
+                           wwe.SetParam(40, -30, 3, 2);
+                           wwe.play();
+                       }
+                       InAOI = false;
+                   }
+                   else
+                   {
+                       //普通chatevent
+                       EventManager.Fire("Event.OnEventHandler.star", new Dictionary<string, string>() {
+                       {"content", msg}, {"isImportant", "1"}, {"keepTime", "" + (evt.KeepTimeMS/1000)}
+                   });
+                   }
+               }
+           }
+           else if (e is CommonAI.Zone.ZoneEvent)
            {
-               string result = "";
-               if (evt_param.Length >= 3 && evt_param[2] != null)
+               if (e is BubbleTalkEvent)
                {
-                   //根据参数个数 依次填值
-                   string[] par = evt_param[2].Split('.');
-                   if (par != null && par.Length > 0)
+                   BubbleTalkEvent evt = e as BubbleTalkEvent;
+                   if (evt.TalkInfos != null)
                    {
-                       switch (par.Length)
+                       foreach (var info in evt.TalkInfos)
                        {
-                           case 1:
+                           System.Action callback = delegate ()
+                           {
+                               if (info.TalkUnit == 0)
                                {
-                                   result = Average(dic["MsgContent"] as string, par[0]);
-                                   break;
+                                   YXJDebug.logError("旁白气泡还没有实现>{0}", info.TalkContent);
+                                   return;
                                }
-                           case 2:
+
+                               ComAIUnit unit = GetUnitById(info.TalkUnit) as ComAIUnit;
+                               if (unit == null)
                                {
-                                   result = Average(dic["MsgContent"] as string, par[0], par[1]);
-                                   break;
+                                   if (info.TalkContent != "bubblechat")
+                                   {
+                                       YXJDebug.logDebug(">BubbleTalkEvent unit not exist: {0}>>{1}", info.TalkUnit, info.TalkContent);
+                                   }
+                                   return;
                                }
-                           case 3:
+
+                               if (info.TalkContent == "bubblechat")
                                {
-                                   result = Average(dic["MsgContent"] as string, par[0], par[1], par[2]);
-                                   break;
+                                   UIBridgeManager.Instance.QuestUIBridge.BubbleTalkEventSend(unit);
                                }
-                           case 4:
+                               else
                                {
-                                   result = Average(dic["MsgContent"] as string, par[0], par[1], par[2], par[3]);
-                                   break;
+                                   var txt = ConfigMgr.Instance.TxtCfg.GetTextByKey("GameEditor_" + info.TalkContent);
+                                   unit.AddBubbleChat(txt, info.TalkKeepTimeMS / 1000);
                                }
-                           case 5:
+
+                               if (!string.IsNullOrEmpty(info.TalkActionType))
                                {
-                                   result = Average(dic["MsgContent"] as string, par[0], par[1], par[2], par[3], par[4]);
-                                   break;
+                                   unit.PlayAnimationWhileIdle(info.TalkActionType);
                                }
+                           };
+
+                           if (info.TalkDelayTimeMS > 0)
+                           {
+                               GameGlobal.Instance.StartCoroutine(WaitForSeconds(info.TalkDelayTimeMS / 1000, callback));
+                           }
+                           else
+                           {
+                               callback.Invoke();
+                           }
                        }
                    }
                }
-               else
+               else if (e is AddEffectEvent && battleManager != null)
                {
-                   //没有参数
-                   result = (dic["MsgContent"] as string);
+                   AddEffectEvent evt = e as AddEffectEvent;
+                   if (evt.hostId == 0 || GetUnitById(evt.hostId) != null)
+                   {
+                       Vector3 pos = battleManager.GetU3DPosByUnitCell(evt.x, evt.y);
+                       pos = ComAICell.AdjustHeight(pos);
+                       Quaternion rotation = Quaternion.Euler(0, evt.direction * Mathf.Rad2Deg + 90, 0);
+                       EffectPlayer.SetRotationOnetime(rotation); //--->这个功能加个参数不就好了 →_→
+                       EffectPlayer.Play(evt.effect, pos, false);
+                   }
                }
-               //
-               EventManager.Fire("Event.OnEventHandler.star", new Dictionary<string, string>() {
-               {"content", result}, {"keepTime", "" + (evt.KeepTimeMS/1000)}, {"content_is_text", "true"}
-           });
-           }
-           else
-           {
-               YXJDebug.logError("config not exist >" + msg);
-           }
-       }
-       else if (evt_param.Length == 2)
-       {
-           string funcName = "GlobalHooks." + evt_param[0];
-           object[] param = evt_param[1].Split(',');
-           //Client.GetMainState().GetFunction(funcName).LazyCall(param);
-           if (param.Length == 0)
-               Client.GetMainState().Call(funcName, Client.LogMiss);
-           else if (param.Length == 1)
-               Client.GetMainState().Call(funcName, param[0], Client.LogMiss);
-           else if (param.Length == 2)
-               Client.GetMainState().Call(funcName, param[0], param[1], Client.LogMiss);
-           else if (param.Length == 3)
-               Client.GetMainState().Call(funcName, param[0], param[1], param[2], Client.LogMiss);
-           else if (param.Length == 4)
-               Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], Client.LogMiss);
-           else if (param.Length == 5)
-               Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], param[4], Client.LogMiss);
-           else
-           {
-               YXJDebug.logError("BattleClientBase.OnEventHandler Error!funcName is {0}", funcName);
-           }
-       }
-       else
-       {
-           //位面进入退出效果
-           if (msg == "EnterAOI")
-           {
-               var wwe = Camera.main.GetComponent<WaterWaveEffect>();
-               if (wwe != null)
+               else if (e is AddEffectEvent2 && battleManager != null)
                {
-                   wwe.SetParam(40, -30, 3, 2);
-                   wwe.play();
+                   AddEffectEvent2 evt = e as AddEffectEvent2;
+                   if (evt.hostId == 0 || GetUnitById(evt.hostId) != null)
+                   {
+                       Vector3 pos = battleManager.GetU3DPosByUnitCell(evt.x, evt.y);
+                       pos = ComAICell.AdjustHeight(pos);
+                       Vector3 targetPos = battleManager.GetU3DPosByUnitCell(evt.TargetX, evt.TargetY);
+                       EffectPlayer.PlayLocal(evt.effect, pos, false, 0, 0, 0, 0, evt.ET, targetPos, evt.FollowActor);
+                   }
                }
-               //GameAlertManager.Instance.setAutoAnimiVisible(false);
-               InAOI = true;
-           }
-           else if (msg == "LeaveAOI")
-           {
-               var wwe = Camera.main.GetComponent<WaterWaveEffect>();
-               if (wwe != null)
+               else if (e is SyncEnvironmentVarEvent)
                {
-                   wwe.SetParam(40, -30, 3, 2);
-                   wwe.play();
+                   SyncEnvironmentVarEvent evt = e as SyncEnvironmentVarEvent;
+                   UIBridgeManager.Instance.BattleUIBridge.EnvironmentVarChange(evt.Key, evt.Value);
                }
-               InAOI = false;
-           }
-           else
-           {
-               //普通chatevent
-               EventManager.Fire("Event.OnEventHandler.star", new Dictionary<string, string>() {
-               {"content", msg}, {"isImportant", "1"}, {"keepTime", "" + (evt.KeepTimeMS/1000)}
-           });
-           }
-       }
-   }
-   else if (e is CommonAI.Zone.ZoneEvent)
-   {
-       if (e is BubbleTalkEvent)
-       {
-           BubbleTalkEvent evt = e as BubbleTalkEvent;
-           if (evt.TalkInfos != null)
-           {
-               foreach (var info in evt.TalkInfos)
+               else if (e is ScriptCommandEvent)
                {
-                   System.Action callback = delegate ()
+                   ScriptCommandEvent evt = e as ScriptCommandEvent;
+                   string[] evt_param = evt.message.Split('|');
+                   if (evt_param.Length == 2)
                    {
-                       if (info.TalkUnit == 0)
-                       {
-                           YXJDebug.logError("旁白气泡还没有实现>{0}", info.TalkContent);
-                           return;
-                       }
-
-                       ComAIUnit unit = GetUnitById(info.TalkUnit) as ComAIUnit;
-                       if (unit == null)
-                       {
-                           if (info.TalkContent != "bubblechat")
-                           {
-                               YXJDebug.logDebug(">BubbleTalkEvent unit not exist: {0}>>{1}", info.TalkUnit, info.TalkContent);
-                           }
-                           return;
-                       }
-
-                       if (info.TalkContent == "bubblechat")
-                       {
-                           UIBridgeManager.Instance.QuestUIBridge.BubbleTalkEventSend(unit);
-                       }
+                       object[] param = evt_param[1].Split(',');
+                       string funcName = "GlobalHooks." + evt_param[0];
+                       if (param.Length == 0)
+                           Client.GetMainState().Call(funcName, Client.LogMiss);
+                       else if (param.Length == 1)
+                           Client.GetMainState().Call(funcName, param[0], Client.LogMiss);
+                       else if (param.Length == 2)
+                           Client.GetMainState().Call(funcName, param[0], param[1], Client.LogMiss);
+                       else if (param.Length == 3)
+                           Client.GetMainState().Call(funcName, param[0], param[1], param[2], Client.LogMiss);
+                       else if (param.Length == 4)
+                           Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], Client.LogMiss);
+                       else if (param.Length == 5)
+                           Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], param[4], Client.LogMiss);
                        else
                        {
-                           var txt = ConfigMgr.Instance.TxtCfg.GetTextByKey("GameEditor_" + info.TalkContent);
-                           unit.AddBubbleChat(txt, info.TalkKeepTimeMS / 1000);
-                       }
-
-                       if (!string.IsNullOrEmpty(info.TalkActionType))
-                       {
-                           unit.PlayAnimationWhileIdle(info.TalkActionType);
+                           YXJDebug.logError("BattleClientBase.OnEventHandler Error!funcName is {0}", funcName);
                        }
-                   };
-
-                   if (info.TalkDelayTimeMS > 0)
-                   {
-                       GameGlobal.Instance.StartCoroutine(WaitForSeconds(info.TalkDelayTimeMS / 1000, callback));
-                   }
-                   else
-                   {
-                       callback.Invoke();
                    }
                }
-           }
-       }
-       if (e is AddEffectEvent && battleManager != null)
-       {
-           AddEffectEvent evt = e as AddEffectEvent;
-           if (evt.hostId == 0 || GetUnitById(evt.hostId) != null)
-           {
-               Vector3 pos = battleManager.GetU3DPosByUnitCell(evt.x, evt.y);
-               pos = ComAICell.AdjustHeight(pos);
-               Quaternion rotation = Quaternion.Euler(0, evt.direction * Mathf.Rad2Deg + 90, 0);
-               EffectPlayer.SetRotationOnetime(rotation); //--->这个功能加个参数不就好了 →_→
-               EffectPlayer.Play(evt.effect, pos, false);
-           }
-       }
-       else if (e is AddEffectEvent2 && battleManager != null)
-       {
-           AddEffectEvent2 evt = e as AddEffectEvent2;
-           if (evt.hostId == 0 || GetUnitById(evt.hostId) != null)
-           {
-               Vector3 pos = battleManager.GetU3DPosByUnitCell(evt.x, evt.y);
-               pos = ComAICell.AdjustHeight(pos);
-               Vector3 targetPos = battleManager.GetU3DPosByUnitCell(evt.TargetX, evt.TargetY);
-               EffectPlayer.PlayLocal(evt.effect, pos, false, 0, 0, 0, 0, evt.ET, targetPos, evt.FollowActor);
-           }
-       }
-       else if (e is SyncEnvironmentVarEvent)
-       {
-           SyncEnvironmentVarEvent evt = e as SyncEnvironmentVarEvent;
-           UIBridgeManager.Instance.BattleUIBridge.EnvironmentVarChange(evt.Key, evt.Value);
-       }
-       else if (e is ScriptCommandEvent)
-       {
-           ScriptCommandEvent evt = e as ScriptCommandEvent;
-           string[] evt_param = evt.message.Split('|');
-           if (evt_param.Length == 2)
-           {
-               object[] param = evt_param[1].Split(',');
-               string funcName = "GlobalHooks." + evt_param[0];
-               if (param.Length == 0)
-                   Client.GetMainState().Call(funcName, Client.LogMiss);
-               else if (param.Length == 1)
-                   Client.GetMainState().Call(funcName, param[0], Client.LogMiss);
-               else if (param.Length == 2)
-                   Client.GetMainState().Call(funcName, param[0], param[1], Client.LogMiss);
-               else if (param.Length == 3)
-                   Client.GetMainState().Call(funcName, param[0], param[1], param[2], Client.LogMiss);
-               else if (param.Length == 4)
-                   Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], Client.LogMiss);
-               else if (param.Length == 5)
-                   Client.GetMainState().Call(funcName, param[0], param[1], param[2], param[3], param[4], Client.LogMiss);
+               else if (e is LockActorEvent)
+               {
+                   LockActorEvent evt = e as LockActorEvent;
+                   OnLockActorEvent(evt);
+               }
+               else if (e is ScriptAddUnitEventsB2C)
+               {
+                   ScriptAddUnitEventsB2C evt = e as ScriptAddUnitEventsB2C;
+                   OnScriptAddUnitEvent(evt);
+               }
+               else if (e is ScriptRemoveUnitEventsB2C)
+               {
+                   ScriptRemoveUnitEventsB2C evt = e as ScriptRemoveUnitEventsB2C;
+                   OnScriptRemoveUnitEvents(evt);
+               }
+               else if (e is PlaySoundEventB2CForAll)
+               {
+                   PlaySoundEventB2CForAll evt = e as PlaySoundEventB2CForAll;
+                   XmdsSoundManager.GetXmdsInstance().PlaySound(evt.SoundName);
+               }
+               else if (e is SyncFlagsEvent && mDecoMgr != null)
+               {
+                   mDecoMgr.LoadDecos();
+               }
+               else if (e is ChangeBGMEvent)
+               {
+                   XmdsSoundManager.GetXmdsInstance().ChangeBGM((e as ChangeBGMEvent).FileName);
+               }
+               else if (e is PlayDestoryEffect)
+               {
+                   if (EffectPlayer == null) return;
+                   PlayDestoryEffect destoryEffect = e as PlayDestoryEffect;
+                   Vector3 vec = new Vector3(destoryEffect.X, destoryEffect.Y, destoryEffect.Z);
+                   Quaternion rotation = Quaternion.Euler(0, destoryEffect.Direction * Mathf.Rad2Deg + 90, 0);
+                   LaunchEffect effect = new LaunchEffect();
+                   effect.Name = destoryEffect.EffectName;
+                   EffectPlayer.SetRotationOnetime(rotation);
+                   EffectPlayer.Play(effect, vec, true);
+               }
                else
                {
-                   YXJDebug.logError("BattleClientBase.OnEventHandler Error!funcName is {0}", funcName);
+                   //YXJDebug.logInfo("OnEventHandler not implemented! {0}", e.ToString());
                }
-           }
-       }
-       else if (e is LockActorEvent)
-       {
-           LockActorEvent evt = e as LockActorEvent;
-           OnLockActorEvent(evt);
-       }
-       else if (e is ScriptAddUnitEventsB2C)
-       {
-           ScriptAddUnitEventsB2C evt = e as ScriptAddUnitEventsB2C;
-           OnScriptAddUnitEvent(evt);
-       }
-       else if (e is ScriptRemoveUnitEventsB2C)
-       {
-           ScriptRemoveUnitEventsB2C evt = e as ScriptRemoveUnitEventsB2C;
-           OnScriptRemoveUnitEvents(evt);
-       }
-       else if (e is PlaySoundEventB2CForAll)
-       {
-           PlaySoundEventB2CForAll evt = e as PlaySoundEventB2CForAll;
-           XmdsSoundManager.GetXmdsInstance().PlaySound(evt.SoundName);
-       }
-       else if (e is SyncFlagsEvent && mDecoMgr != null)
-       {
-           mDecoMgr.LoadDecos();
-       }
-       else if (e is ChangeBGMEvent)
-       {
-           XmdsSoundManager.GetXmdsInstance().ChangeBGM((e as ChangeBGMEvent).FileName);
-       }
-       else if (e is PlayDestoryEffect)
-       {
-           if (EffectPlayer == null) return;
-           PlayDestoryEffect destoryEffect = e as PlayDestoryEffect;
-           Vector3 vec = new Vector3(destoryEffect.X, destoryEffect.Y, destoryEffect.Z);
-           Quaternion rotation = Quaternion.Euler(0, destoryEffect.Direction * Mathf.Rad2Deg + 90, 0);
-           LaunchEffect effect = new LaunchEffect();
-           effect.Name = destoryEffect.EffectName;
-           EffectPlayer.SetRotationOnetime(rotation);
-           EffectPlayer.Play(effect, vec, true);
-       }
-       else
-       {
-           //YXJDebug.logInfo("OnEventHandler not implemented! {0}", e.ToString());
-       }
-   }
-}*/
+           }*/
+        }
     }
 }
 

+ 1 - 1
Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattlePushHandler.cs

@@ -7,6 +7,7 @@ using CommonLang;
 
 namespace ET.Client
 {
+    //处理战斗推送的消息
     [MessageHandler(SceneType.Client)]
     public class BattlePushHandler : AMHandler<BattleEventPush>
     {
@@ -21,7 +22,6 @@ namespace ET.Client
                 return;
             }
             var msg = data as CommonLang.Protocol.IMessage;
-            Log.Debug($">>battlePush: {data}");
             BattleMgr.Instance.Layer.ProcessMessage(msg);
 
             /*if ((ushort)BattlePushCnst.FastStreamPush == type)

+ 53 - 0
Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattleUnitFactory.cs

@@ -0,0 +1,53 @@
+using CommonAI.ZoneClient;
+using ET;
+using ET.Client;
+using UnitType = CommonAI.Zone.UnitInfo.UnitType;
+
+class BattleUnitFactory : Singleton<BattleUnitFactory>//, ISingletonUpdate
+{
+    public async ETTask InitAsync()
+    {
+        await ETTask.CompletedTask;
+    }
+
+    public BattleObject Create(ZoneObject zo)
+    {
+        BattleObject unit = null;
+        if(zo is ZoneActor)
+        {
+            unit = ObjectPool.Instance.Fetch<BattleActor>();
+        }
+        else if (zo is ZoneUnit)
+        {
+            ZoneUnit zu = zo as ZoneUnit;
+            switch (zu.Info.UType)
+            {
+                case UnitType.TYPE_PLAYER://玩家单位.
+                    unit = ObjectPool.Instance.Fetch<BattlePlayer>();
+                    break;
+                case UnitType.TYPE_MONSTER://怪物.
+                    unit = ObjectPool.Instance.Fetch<BattleMonster>();
+                    break;
+
+                case UnitType.TYPE_BUILDING://建筑.
+                case UnitType.TYPE_NPC://NPC.
+                case UnitType.TYPE_NEUTRALITY://NPC.
+                case UnitType.TYPE_SUMMON://召唤单位.
+                case UnitType.TYPE_PET:
+                case UnitType.TYPE_TRIGGER: //触发机关
+                default:
+                    Log.Error($"unknow object enter:{zu.Info.UType} ID:{zu.TemplateID}");
+                    break;
+            }
+        }
+        else if (zo is ZoneSpell)
+        {
+            unit = ObjectPool.Instance.Fetch<BattleSpell>();
+        }
+        else if (zo is ZoneItem)//掉落物  
+        {
+        }
+
+        return unit;
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Hotfix/Client/battle/BattleUnitFactory.cs.meta

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

+ 40 - 0
Unity/Assets/Scripts/Codes/Hotfix/Client/battle/UnitListComponentSystem.cs

@@ -0,0 +1,40 @@
+
+namespace ET.Client
+{
+    [ObjectSystem]
+    public class UnitListComponentAwakeSystem : AwakeSystem<UnitListComponent>
+    {
+        protected override void Awake(UnitListComponent self)
+        {
+            UnitListComponent.Instance = self;
+            self.RecycleUnits();
+            self.UnitList = new();
+        }
+    }
+
+    [ObjectSystem]
+    public class UnitListComponentDestroySystem : DestroySystem<UnitListComponent>
+    {
+        protected override void Destroy(UnitListComponent self)
+        {
+            self.RecycleUnits();
+            UnitListComponent.Instance = null;
+        }
+    }
+
+    [FriendOf(typeof(UnitListComponent))]
+    public static class UnitListComponentExt
+    {
+        public static void RecycleUnits(this UnitListComponent self)
+        {
+            if(self.UnitList != null)
+            {
+                foreach(var kp in self.UnitList)
+                {
+                    kp.Value.OnSleep();
+                }
+                self.UnitList = null;
+            }
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Hotfix/Client/battle/UnitListComponentSystem.cs.meta

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

+ 1 - 7
Unity/Assets/Scripts/Codes/HotfixView/Client/EntryEvent3_InitClient.cs

@@ -7,13 +7,7 @@
         {
             // 加载配置
             //Root.Instance.Scene.AddComponent<ResourcesComponent>();
-            Root.Instance.Scene.AddComponent<GlobalComponent>();
-
-            //加载战斗相关资源
-            Game.AddSingleton<BattleResourceMgr>();
-            Game.AddSingleton<BattleMgr>();
-            await BattleResourceMgr.Instance.InitAsync();
-            await BattleMgr.Instance.InitAsync();
+            Root.Instance.Scene.AddComponent<GlobalViewComponent>();
 
             Scene clientScene = await SceneFactory.CreateClientScene(1, "Game");
             await EventSystem.Instance.PublishAsync(clientScene, new EventType.AppStartInitFinish());

+ 4 - 2
Unity/Assets/Scripts/Codes/HotfixView/Client/Scene/AfterCreateCurrentScene_AddComponent.cs

@@ -1,4 +1,4 @@
-namespace ET.Client
+namespace ET.Client
 {
     [Event(SceneType.Current)]
     public class AfterCreateCurrentScene_AddComponent: AEvent<EventType.AfterCreateCurrentScene>
@@ -7,7 +7,9 @@ namespace ET.Client
         {
             //scene.AddComponent<UIComponent>();
             //scene.AddComponent<ResourcesLoaderComponent>();
+            scene.AddComponent<ModelViewComponent>();
+            scene.AddComponent<UnitListComponent>();
             await ETTask.CompletedTask;
         }
     }
-}
+}

+ 29 - 0
Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnDestroyZoneObject.cs

@@ -0,0 +1,29 @@
+using UnityEngine;
+
+namespace ET.Client
+{
+    [Event(SceneType.Current)]
+    public class OnDestroyZoneObject : AEvent<EventType.OnDestroyZoneObject>
+    {
+        protected override async ETTask Run(Scene scene, EventType.OnDestroyZoneObject args)
+        {
+            await DestroyUnitModel(args.Object);
+        }
+
+        private async ETTask DestroyUnitModel(BattleObject unit)
+        {
+            ModelViewComponent.Instance.RemoveChild(unit.Id);
+
+            if (unit is BattleActor)
+            {
+                //相机跟随主角
+                //ModelViewComponent.Instance.AddComponent<CameraComponent>().Unit = unit;
+
+                //固定视角相机
+                var camera = Camera.main;
+                //camera.transform.position = new Vector3(unit.Position.x, 7, unit.Position.z - 15);
+            }
+            await ETTask.CompletedTask;
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnDestroyZoneObject.cs.meta

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

+ 45 - 0
Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnNewZoneObject.cs

@@ -0,0 +1,45 @@
+using UnityEngine;
+
+namespace ET.Client
+{
+    [Event(SceneType.Current)]
+    public class OnNewZoneObject : AEvent<EventType.OnNewZoneObject>
+    {
+        protected override async ETTask Run(Scene scene, EventType.OnNewZoneObject args)
+        {
+            var bo = args.Object;
+            if(bo is BattleUnit)
+            {
+                await CreatUnitModel(bo as BattleUnit);
+            }
+            else
+            {
+                Log.Error("unknow new object");
+            }
+        }
+
+        private async ETTask CreatUnitModel(BattleUnit unit)
+        {
+            var zu = unit.ZUnit;
+            
+            var handle = await YooAssetProxy.LoadAssetAsync<GameObject>($"Unit_{zu.Info.FileName}");
+            var prefab = handle.GetAssetObject<GameObject>();
+            GameObject go = UnityEngine.Object.Instantiate(prefab, GlobalViewComponent.Instance.Unit, true);
+            go.transform.position = new Vector3(0, 0, 0);
+            go.transform.rotation = Quaternion.identity;
+
+            ModelViewComponent.Instance.AddChildWithId<AnimatorComponent, GameObject>(unit.Id, go, true);
+
+            if (unit is BattleActor)
+            {
+                //相机跟随主角
+                //ModelViewComponent.Instance.AddComponent<CameraComponent>().Unit = unit;
+
+                //固定视角相机
+                var camera = Camera.main;
+                var pos = go.transform.position;
+                camera.transform.position = new Vector3(pos.x, 7, pos.z - 15);
+            }
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/HotfixView/Client/Unit/OnNewZoneObject.cs.meta

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

+ 8 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 20f2e04a5e28ac64f9bd8e97a6ff568f
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b0c6cb43bbac1704bacdb6ab68c2c986
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 45 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleActor.cs

@@ -0,0 +1,45 @@
+using CommonAI.ZoneClient;
+using ET;
+using System.Diagnostics;
+
+public class BattleActor : BattlePlayer
+{
+    public override void OnAwake(ZoneObject zo)
+    {
+        base.OnAwake(zo);
+        ZoneActor za = zo as ZoneActor;
+        za.IsFollow = false;
+        za.OnStartPickObject += OnStartPickObject;
+        za.OnStopPickObject += OnStopPickObject;
+        za.OnSkillChanged += OnSkillChanged;
+        za.OnClickSkillSimulationEvent += OnClickSkillSimulationEvent;
+    }
+
+    private void OnSkillChanged(ZoneUnit.SkillOption op, ZoneUnit unit, int baseSkillID, params int[] skills)
+    {
+        Log.Debug(">OnSkillChanged> {0}, base:{1},skills:{2}", op, baseSkillID, skills != null ? skills.Length : 0);
+        //SkillOption.Init的不用管,SkillBar.InitSkill直接从UserData读
+        //SkillOpetion.Active不明意义,未处理
+        if (op == ZoneUnit.SkillOption.Reset)
+        {
+        }
+        else if (op == ZoneUnit.SkillOption.Add || op == ZoneUnit.SkillOption.Remove)
+        {
+        }
+    }
+
+    private void OnStopPickObject(ZoneUnit unit, CommonAI.Zone.UnitStopPickObjectEvent stop)
+    {
+        Log.Error("unhande event: OnStopPickObject");
+    }
+
+    private void OnStartPickObject(ZoneUnit unit, CommonLang.TimeExpire<CommonAI.Zone.UnitStartPickObjectEvent> start)
+    {
+        Log.Error("unhande event: OnStartPickObject");
+    }
+
+    private void OnClickSkillSimulationEvent(ZoneUnit unit, CommonAI.Zone.Helper.SimulationSkillEnum type)
+    {
+        Log.Error("unhande event: OnClickSkillSimulationEvent");
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleActor.cs.meta

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

+ 9 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleMonster.cs

@@ -0,0 +1,9 @@
+using CommonAI.ZoneClient;
+
+public class BattleMonster : BattleUnit
+{
+    public override void OnAwake(ZoneObject zo)
+    {
+        base.OnAwake(zo);
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleMonster.cs.meta

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

+ 48 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleObject.cs

@@ -0,0 +1,48 @@
+using CommonAI.ZoneClient;
+using ET;
+using ET.Client;
+using ET.EventType;
+
+public class BattleObject
+{
+    protected ZoneObject ZoneObject;
+
+    public uint Id { get { return ZoneObject.ObjectID; } }
+
+    public BattleObject() { }
+
+    public virtual void OnAwake(ZoneObject zo)
+    {
+        ZoneObject = zo;
+        EventSystem.Instance.Publish(CurrentScene(), new OnNewZoneObject() { Object = this });
+    }
+
+    public virtual void OnSleep()
+    {
+        EventSystem.Instance.Publish(CurrentScene(), new OnDestroyZoneObject() { Object = this });
+        ObjectPool.Instance.Recycle(this);
+    }
+
+    private static Scene _CurrentSceneCache = null;
+    public static Scene CurrentScene()
+    {
+        if (_CurrentSceneCache == null)
+        {
+            var cs = ClientSceneManagerComponent.Instance.GetChild<Scene>(UnitListComponent.Instance.DomainZone());
+            _CurrentSceneCache = cs.GetComponent<CurrentScenesComponent>().Scene;
+        }
+        return _CurrentSceneCache;
+    }
+
+
+    [Event(SceneType.Current)]
+    public class AfterCreateCurrentScene_Battle : AEvent<ET.EventType.AfterCreateCurrentScene>
+    {
+        protected override async ETTask Run(Scene scene, ET.EventType.AfterCreateCurrentScene args)
+        {
+            _CurrentSceneCache = null;
+            await ETTask.CompletedTask;
+        }
+    }
+
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleObject.cs.meta

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

+ 9 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattlePlayer.cs

@@ -0,0 +1,9 @@
+using CommonAI.ZoneClient;
+
+public class BattlePlayer : BattleUnit
+{
+    public override void OnAwake(ZoneObject zo)
+    {
+        base.OnAwake(zo);
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattlePlayer.cs.meta

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

+ 5 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleSpell.cs

@@ -0,0 +1,5 @@
+using CommonAI.ZoneClient;
+
+public class BattleSpell : BattleObject
+{
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleSpell.cs.meta

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

+ 110 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleUnit.cs

@@ -0,0 +1,110 @@
+using CommonAI.Zone;
+using CommonAI.Zone.Helper;
+using CommonAI.ZoneClient;
+using System;
+
+public class BattleUnit : BattleObject
+{
+    public BattleUnit() { }
+    public ZoneUnit ZUnit { get { return ZoneObject as ZoneUnit; } }
+
+    public override void OnAwake(ZoneObject zo)
+    {
+        base.OnAwake(zo);
+        var zu = zo as ZoneUnit;
+        zu.OnActionChanged += OnActionChanged;
+        zu.OnSkillActionChanged += OnSkillActionChanged;
+        zu.OnHPChanged += OnHPChanged;
+        zu.OnMPChanged += OnMPChanged;
+        zu.OnMaxHPChanged += OnMaxHPChanged;
+        zu.OnMaxMPChanged += OnMaxMPChanged;
+        zu.OnLaunchSkill += OnLaunchSkill;
+        zu.OnBuffAdded += OnBuffAdded;
+        zu.OnBuffRemoved += OnBuffRemoved;
+        zu.OnBuffChanged += OnBuffChanged;
+        //新增层Buff移除
+        zu.OnRemoveBuffByOverlayLevel += OnRemoveBuffByOverlayLevel;
+        //新增子状态
+        zu.OnActionSubStatusChanged += OnActionSubStatusChanged;
+
+        zu.OnDoEvent += OnLayerObjectEvent;
+    }
+
+    protected virtual void OnActionSubStatusChanged(ZoneUnit unit, byte status, object evt)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnRemoveBuffByOverlayLevel(ZoneUnit unit, ZoneUnit.BuffState buff)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnBuffChanged(ZoneUnit unit, ZoneUnit.BuffState buff)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnBuffRemoved(ZoneUnit unit, ZoneUnit.BuffState buff)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnBuffAdded(ZoneUnit unit, ZoneUnit.BuffState buff)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnLaunchSkill(ZoneUnit unit, ZoneUnit.SkillState skill, UnitLaunchSkillEvent evt)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnMaxMPChanged(ZoneUnit unit, int oldMaxMP, int newMaxMP)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnMaxHPChanged(ZoneUnit unit, int oldMaxHP, int newMaxHP)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnMPChanged(ZoneUnit unit, int oldMP, int newMP)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnHPChanged(ZoneUnit unit, int oldHP, int newHP)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnSkillActionChanged(ZoneUnit unit, ZoneUnit.SkillState skill, byte index)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected virtual void OnActionChanged(ZoneUnit unit, UnitActionStatus status, object evt)
+    {
+    }
+
+    protected virtual void OnLayerObjectEvent(ZoneObject obj, CommonAI.Zone.ObjectEvent e)
+    {
+        /*RegistZoneEvent<BattleHintNumberB2C>((data) =>
+        {
+            BattleHintNumberB2C evt = data as BattleHintNumberB2C;
+            ShowHint(evt.Value, evt.State, evt.TargetObjID);
+        });
+        RegistZoneEvent<BattleFloatTipsEventB2C>((data) =>
+        {
+            BattleFloatTipsEventB2C evt = data as BattleFloatTipsEventB2C;
+            ShowTipHint(evt.Type);
+        });
+        RegistZoneEvent<BubbleTipsEventB2C>((data) =>
+        {
+            BubbleTipsEventB2C evt = data as BubbleTipsEventB2C;
+            AddBubbleChat(evt.Msg, 5);
+        });*/
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/Battle/unit/BattleUnit.cs.meta

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

+ 13 - 0
Unity/Assets/Scripts/Codes/Model/Client/EventTypeClient.cs

@@ -0,0 +1,13 @@
+namespace ET
+{
+    namespace EventType
+    {
+        public struct OnNewZoneObject {
+            public BattleObject Object;
+        }
+        public struct OnDestroyZoneObject
+        {
+            public BattleObject Object;
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/EventTypeClient.cs.meta

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

+ 15 - 0
Unity/Assets/Scripts/Codes/Model/Client/Unit/UnitListComponent.cs

@@ -0,0 +1,15 @@
+
+using CommonLang;
+
+namespace ET.Client
+{
+    [ComponentOf(typeof(Scene))]
+    public class UnitListComponent : Entity, IAwake, IDestroy
+    {
+        [StaticField]
+        public static UnitListComponent Instance;
+
+        public BattleActor Actor { get; set; }
+        public HashMap<uint, BattleObject> UnitList;
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Codes/Model/Client/Unit/UnitListComponent.cs.meta

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