Bladeren bron

增加ReplayUpdater,用于播放Replay

tanghai 2 jaren geleden
bovenliggende
commit
57742dab3a
27 gewijzigde bestanden met toevoegingen van 244 en 151 verwijderingen
  1. 11 5
      Unity/Assets/Res/Mat/Urp.mat
  2. 1 1
      Unity/Assets/Res/UniversalRenderPipelineAsset.asset
  3. 2 2
      Unity/Assets/Scenes/Map1.unity
  4. BIN
      Unity/Assets/Scenes/Map1/LightingData.asset
  5. BIN
      Unity/Assets/Scenes/Map1/Lightmap-0_comp_dir.png
  6. BIN
      Unity/Assets/Scenes/Map1/Lightmap-0_comp_light.exr
  7. 1 1
      Unity/Assets/Scenes/Map1Settings.lighting
  8. 2 3
      Unity/Assets/Scripts/Hotfix/Client/LockStep/LSSceneChangeHelper.cs
  9. 8 8
      Unity/Assets/Scripts/Hotfix/Client/LockStep/OneFrameInputsHandler.cs
  10. 42 0
      Unity/Assets/Scripts/Hotfix/Client/LockStep/ReplayUpdaterSystem.cs
  11. 1 1
      Unity/Assets/Scripts/Hotfix/Client/LockStep/ReplayUpdaterSystem.cs.meta
  12. 6 6
      Unity/Assets/Scripts/Hotfix/Client/LockStep/RoomClientUpdaterSystem.cs
  13. 1 1
      Unity/Assets/Scripts/Hotfix/Server/LockStep/Map/C2Room_ChangeSceneFinishHandler.cs
  14. 9 3
      Unity/Assets/Scripts/Hotfix/Server/LockStep/Map/FrameMessageHandler.cs
  15. 1 2
      Unity/Assets/Scripts/Hotfix/Server/LockStep/Map/RoomManagerComponentSystem.cs
  16. 4 4
      Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/RoomServerUpdaterSystem.cs
  17. 36 10
      Unity/Assets/Scripts/Hotfix/Share/LockStep/LSHelper.cs
  18. 36 15
      Unity/Assets/Scripts/Hotfix/Share/LockStep/RoomSystem.cs
  19. 1 1
      Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewSystem.cs
  20. 7 0
      Unity/Assets/Scripts/Model/Client/LockStep/ReplayUpdater.cs
  21. 1 1
      Unity/Assets/Scripts/Model/Client/LockStep/ReplayUpdater.cs.meta
  22. 19 38
      Unity/Assets/Scripts/Model/Share/LockStep/FrameBuffer.cs
  23. 18 0
      Unity/Assets/Scripts/Model/Share/LockStep/Record.cs
  24. 11 0
      Unity/Assets/Scripts/Model/Share/LockStep/Record.cs.meta
  25. 0 31
      Unity/Assets/Scripts/Model/Share/LockStep/RollbackHelper.cs
  26. 26 3
      Unity/Assets/Scripts/Model/Share/LockStep/Room.cs
  27. 0 15
      Unity/Assets/Scripts/Model/Share/LockStep/SaveData.cs

+ 11 - 5
Unity/Assets/Res/Mat/Urp.mat

@@ -15,18 +15,20 @@ MonoBehaviour:
   version: 5
 --- !u!21 &2100000
 Material:
-  serializedVersion: 6
+  serializedVersion: 8
   m_ObjectHideFlags: 0
   m_CorrespondingSourceObject: {fileID: 0}
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_Name: Urp
-  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
-  m_ShaderKeywords: _ENVIRONMENTREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF _SPECULAR_SETUP
+  m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
+  m_ValidKeywords:
+  - _SPECULAR_COLOR
+  m_InvalidKeywords: []
   m_LightmapFlags: 4
   m_EnableInstancingVariants: 0
   m_DoubleSidedGI: 0
-  m_CustomRenderQueue: 2000
+  m_CustomRenderQueue: -1
   stringTagMap:
     RenderType: Opaque
   disabledShaderPasses: []
@@ -104,6 +106,7 @@ Material:
     - _EnvironmentReflections: 0
     - _GlossMapScale: 0
     - _Glossiness: 0
+    - _GlossinessSource: 0
     - _GlossyReflections: 0
     - _Metallic: 0
     - _OcclusionStrength: 1
@@ -111,8 +114,11 @@ Material:
     - _QueueOffset: 0
     - _ReceiveShadows: 1
     - _SampleGI: 0
+    - _Shininess: 0
     - _Smoothness: 0.5
+    - _SmoothnessSource: 0
     - _SmoothnessTextureChannel: 0
+    - _SpecSource: 0
     - _SpecularHighlights: 0
     - _SrcBlend: 1
     - _Surface: 0
@@ -122,5 +128,5 @@ Material:
     - _BaseColor: {r: 1, g: 1, b: 1, a: 1}
     - _Color: {r: 1, g: 1, b: 1, a: 1}
     - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
-    - _SpecColor: {r: 0.2, g: 0.2, b: 0.2, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 0.5}
   m_BuildTextureStacks: []

+ 1 - 1
Unity/Assets/Res/UniversalRenderPipelineAsset.asset

@@ -34,7 +34,7 @@ MonoBehaviour:
   m_MainLightShadowsSupported: 1
   m_MainLightShadowmapResolution: 2048
   m_AdditionalLightsRenderingMode: 1
-  m_AdditionalLightsPerObjectLimit: 4
+  m_AdditionalLightsPerObjectLimit: 0
   m_AdditionalLightShadowsSupported: 0
   m_AdditionalLightsShadowmapResolution: 512
   m_AdditionalLightsShadowResolutionTierLow: 128

+ 2 - 2
Unity/Assets/Scenes/Map1.unity

@@ -7970,7 +7970,7 @@ Light:
   serializedVersion: 10
   m_Type: 1
   m_Shape: 0
-  m_Color: {r: 0.8962264, g: 0.8962264, b: 0.8962264, a: 1}
+  m_Color: {r: 0.7169812, g: 0.7169812, b: 0.7169812, a: 1}
   m_Intensity: 1
   m_Range: 10
   m_SpotAngle: 30
@@ -8010,7 +8010,7 @@ Light:
     serializedVersion: 2
     m_Bits: 4294967295
   m_RenderingLayerMask: 1
-  m_Lightmapping: 1
+  m_Lightmapping: 2
   m_LightShadowCasterMode: 0
   m_AreaSize: {x: 1, y: 1}
   m_BounceIntensity: 1

BIN
Unity/Assets/Scenes/Map1/LightingData.asset


BIN
Unity/Assets/Scenes/Map1/Lightmap-0_comp_dir.png


BIN
Unity/Assets/Scenes/Map1/Lightmap-0_comp_light.exr


+ 1 - 1
Unity/Assets/Scenes/Map1Settings.lighting

@@ -10,7 +10,7 @@ LightingSettings:
   serializedVersion: 4
   m_GIWorkflowMode: 1
   m_EnableBakedLightmaps: 1
-  m_EnableRealtimeLightmaps: 0
+  m_EnableRealtimeLightmaps: 1
   m_RealtimeEnvironmentLighting: 1
   m_BounceScale: 1
   m_AlbedoBoost: 1

+ 2 - 3
Unity/Assets/Scripts/Hotfix/Client/LockStep/LSSceneChangeHelper.cs

@@ -19,9 +19,8 @@ namespace ET.Client
             // 等待Room2C_EnterMap消息
             WaitType.Wait_Room2C_Start waitRoom2CStart = await clientScene.GetComponent<ObjectWait>().Wait<WaitType.Wait_Room2C_Start>();
 
-            LSWorld lsWorld = new(SceneType.LockStepClient);
-            room.AddComponent(lsWorld);
-            room.Init(waitRoom2CStart.Message);
+            room.LSWorld = new LSWorld(SceneType.LockStepClient);
+            room.Init(waitRoom2CStart.Message.UnitInfo, waitRoom2CStart.Message.StartTime);
             
             room.AddComponent<RoomClientUpdater>();
 

+ 8 - 8
Unity/Assets/Scripts/Hotfix/Client/LockStep/OneFrameInputsHandler.cs

@@ -10,19 +10,19 @@ namespace ET.Client
             Room room = session.DomainScene().GetComponent<Room>();
             FrameBuffer frameBuffer = room.FrameBuffer;
 
-            int frame = room.RealFrame + 1;
+            int frame = room.AuthorityFrame + 1;
 
-            ++room.RealFrame;
+            ++room.AuthorityFrame;
             // 服务端返回的消息比预测的还早
-            if (room.RealFrame > room.PredictionFrame)
+            if (room.AuthorityFrame > room.PredictionFrame)
             {
-                OneFrameInputs realFrame = frameBuffer[room.RealFrame];
-                input.CopyTo(realFrame);
+                OneFrameInputs authorityFrame = frameBuffer.FrameInputs(room.AuthorityFrame);
+                input.CopyTo(authorityFrame);
                 return;
             }
             
             // 服务端返回来的消息,跟预测消息对比
-            OneFrameInputs predictionInput = frameBuffer[frame];
+            OneFrameInputs predictionInput = frameBuffer.FrameInputs(frame);
             // 对比失败有两种可能,
             // 1是别人的输入预测失败,这种很正常,
             // 2 自己的输入对比失败,这种情况是自己发送的消息比服务器晚到了,服务器使用了你的上一次输入
@@ -30,8 +30,8 @@ namespace ET.Client
             if (input != predictionInput)
             {
                 input.CopyTo(predictionInput);
-                // 回滚到frameBuffer.RealFrame
-                LSHelper.Rollback(room, room.RealFrame);
+                // 回滚到frameBuffer.AuthorityFrame
+                LSHelper.Rollback(room, room.AuthorityFrame);
             }
 
             // 回收消息,减少GC

+ 42 - 0
Unity/Assets/Scripts/Hotfix/Client/LockStep/ReplayUpdaterSystem.cs

@@ -0,0 +1,42 @@
+using System;
+
+namespace ET.Client
+{
+    [FriendOf(typeof(ReplayUpdater))]
+    public static class ReplayComponentSystem
+    {
+        [ObjectSystem]
+        public class AwakeSystem: AwakeSystem<ReplayUpdater, Record>
+        {
+            protected override void Awake(ReplayUpdater self, Record record)
+            {
+                self.Record = record;
+                self.GetParent<Room>().Init(self.Record.UnitInfos, TimeHelper.ServerFrameTime());
+            }
+        }
+
+        [ObjectSystem]
+        public class UpdateSystem: UpdateSystem<ReplayUpdater>
+        {
+            protected override void Update(ReplayUpdater self)
+            {
+                self.Update();
+            }
+        }
+
+        private static void Update(this ReplayUpdater self)
+        {
+            Room room = self.GetParent<Room>();
+            long timeNow = TimeHelper.ServerFrameTime();
+            
+            if (timeNow < room.FixedTimeCounter.FrameTime(room.AuthorityFrame + 1))
+            {
+                return;
+            }
+
+            ++room.AuthorityFrame;
+            OneFrameInputs oneFrameInputs = self.Record.FrameInputs[room.AuthorityFrame];
+            room.Update(oneFrameInputs, room.AuthorityFrame);
+        }
+    }
+}

+ 1 - 1
Unity/Assets/Scripts/Model/Share/LockStep/RollbackHelper.cs.meta → Unity/Assets/Scripts/Hotfix/Client/LockStep/ReplayUpdaterSystem.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 70d280daa251c4974982685b04d5ac9a
+guid: 622cdcb6fe92843b08630e4b7e491f09
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 6 - 6
Unity/Assets/Scripts/Hotfix/Client/LockStep/RoomClientUpdaterSystem.cs

@@ -35,7 +35,7 @@ namespace ET.Client
             }
 
             // 最多只预测5帧
-            if (room.PredictionFrame - room.RealFrame > 5)
+            if (room.PredictionFrame - room.AuthorityFrame > 5)
             {
                 return;
             }
@@ -56,21 +56,21 @@ namespace ET.Client
             Room room = self.GetParent<Room>();
             FrameBuffer frameBuffer = room.FrameBuffer;
             
-            if (frame <= room.RealFrame)
+            if (frame <= room.AuthorityFrame)
             {
-                return frameBuffer[frame];
+                return frameBuffer.FrameInputs(frame);
             }
             
             // predict
-            OneFrameInputs predictionFrame = frameBuffer[frame];
+            OneFrameInputs predictionFrame = frameBuffer.FrameInputs(frame);
             if (predictionFrame == null)
             {
                 throw new Exception($"get frame is null: {frame}, max frame: {frameBuffer.MaxFrame}");
             }
             
             frameBuffer.MoveForward(frame);
-            OneFrameInputs realFrame = frameBuffer[room.RealFrame];
-            realFrame?.CopyTo(predictionFrame);
+            OneFrameInputs authorityFrame = frameBuffer.FrameInputs(room.AuthorityFrame);
+            authorityFrame?.CopyTo(predictionFrame);
             predictionFrame.Inputs[self.MyId] = self.Input;
             
             return predictionFrame;

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/LockStep/Map/C2Room_ChangeSceneFinishHandler.cs

@@ -29,7 +29,7 @@ namespace ET.Server
                 });
             }
 
-            room.Init(room2CStart);
+            room.Init(room2CStart.UnitInfo, room2CStart.StartTime);
 
             room.AddComponent<RoomServerUpdater>();
 

+ 9 - 3
Unity/Assets/Scripts/Hotfix/Server/LockStep/Map/FrameMessageHandler.cs

@@ -18,13 +18,19 @@ namespace ET.Server
                 ActorLocationSenderComponent.Instance.Get(LocationType.GateSession).Send(message.PlayerId, new Room2C_AdjustUpdateTime() {DiffTime = diffTime});
             }
 
-            if (message.Frame < room.RealFrame)  // 小于RealFrame,丢弃
+            if (message.Frame < room.AuthorityFrame)  // 小于AuthorityFrame,丢弃
             {
-                Log.Warning($"FrameMessage discard: {message}");
+                Log.Warning($"FrameMessage < AuthorityFrame discard: {message}");
+                return;
+            }
+
+            if (message.Frame > room.AuthorityFrame + 10)  // 大于AuthorityFrame + 10,丢弃
+            {
+                Log.Warning($"FrameMessage > AuthorityFrame + 10 discard: {message}");
                 return;
             }
             
-            OneFrameInputs oneFrameInputs = frameBuffer[message.Frame];
+            OneFrameInputs oneFrameInputs = frameBuffer.FrameInputs(message.Frame);
             if (oneFrameInputs == null)
             {
                 Log.Error($"FrameMessageHandler get frame is null: {message.Frame}, max frame: {frameBuffer.MaxFrame}");

+ 1 - 2
Unity/Assets/Scripts/Hotfix/Server/LockStep/Map/RoomManagerComponentSystem.cs

@@ -13,8 +13,7 @@ namespace ET.Server
             
             room.AddComponent<RoomServerComponent, Match2Map_GetRoom>(request);
 
-            LSWorld lsWorld = new(SceneType.LockStepServer);
-            room.AddComponent(lsWorld);
+            room.LSWorld = new LSWorld(SceneType.LockStepServer);
 
             room.AddComponent<MailBoxComponent, MailboxType>(MailboxType.UnOrderMessageDispatcher);
             

+ 4 - 4
Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/RoomServerUpdaterSystem.cs

@@ -21,14 +21,14 @@ namespace ET.Server
             long timeNow = TimeHelper.ServerFrameTime();
             
             
-            int frame = room.RealFrame + 1;
+            int frame = room.AuthorityFrame + 1;
             if (timeNow < room.FixedTimeCounter.FrameTime(frame))
             {
                 return;
             }
 
             OneFrameInputs oneFrameInputs = self.GetOneFrameMessage(frame);
-            ++room.RealFrame;
+            ++room.AuthorityFrame;
 
             OneFrameInputs sendInput = new();
             oneFrameInputs.CopyTo(sendInput);
@@ -42,7 +42,7 @@ namespace ET.Server
         {
             Room room = self.GetParent<Room>();
             FrameBuffer frameBuffer = room.FrameBuffer;
-            OneFrameInputs oneFrameInputs = frameBuffer[frame];
+            OneFrameInputs oneFrameInputs = frameBuffer.FrameInputs(frame);
             if (oneFrameInputs == null)
             {
                 throw new Exception($"get frame is null: {frame}, max frame: {frameBuffer.MaxFrame}");
@@ -55,7 +55,7 @@ namespace ET.Server
                 return oneFrameInputs;
             }
 
-            OneFrameInputs preFrameInputs = frameBuffer[frame - 1];
+            OneFrameInputs preFrameInputs = frameBuffer.FrameInputs(frame - 1);
             
             // 有人输入的消息没过来,给他使用上一帧的操作
             foreach (long playerId in room.PlayerIds)

+ 36 - 10
Unity/Assets/Scripts/Hotfix/Share/LockStep/LSHelper.cs

@@ -4,35 +4,61 @@ namespace ET
 {
     public static class LSHelper
     {
+        public static void RunRollbackSystem(Entity entity)
+        {
+            if (entity is LSEntity)
+            {
+                return;
+            }
+            
+            LSSington.Instance.Rollback(entity);
+            
+            if (entity.ComponentsCount() > 0)
+            {
+                foreach (var kv in entity.Components)
+                {
+                    RunRollbackSystem(kv.Value);
+                }
+            }
+
+            if (entity.ChildrenCount() > 0)
+            {
+                foreach (var kv in entity.Children)
+                {
+                    RunRollbackSystem(kv.Value);
+                }
+            }
+        }
+        
         // 回滚
         public static void Rollback(Room room, int frame)
         {
             Log.Debug($"roll back start {frame}");
-            room.RemoveComponent<LSWorld>();
+            room.LSWorld.Dispose();
             FrameBuffer frameBuffer = room.FrameBuffer;
             
             // 回滚
-            room.AddComponent(frameBuffer.GetLSWorld(frame));
-            OneFrameInputs realFrameInput = frameBuffer[frame];
+            room.LSWorld = room.GetLSWorld(frame);
+            OneFrameInputs authorityFrameInput = frameBuffer.FrameInputs(frame);
             // 执行RealFrame
-            room.Update(realFrameInput, frame);
+            room.Update(authorityFrameInput, frame);
 
             
             // 重新执行预测的帧
-            for (int i = room.RealFrame + 1; i <= room.PredictionFrame; ++i)
+            for (int i = room.AuthorityFrame + 1; i <= room.PredictionFrame; ++i)
             {
-                OneFrameInputs oneFrameInputs = frameBuffer[i];
-                CopyOtherInputsTo(room, realFrameInput, oneFrameInputs); // 重新预测消息
+                OneFrameInputs oneFrameInputs = frameBuffer.FrameInputs(i);
+                LSHelper.CopyOtherInputsTo(room, authorityFrameInput, oneFrameInputs); // 重新预测消息
                 room.Update(oneFrameInputs, i);
             }
             
-            RollbackHelper.Rollback(room);
+            RunRollbackSystem(room);
             
             Log.Debug($"roll back finish {frame}");
         }
-
+        
         // 重新调整预测消息,只需要调整其他玩家的输入
-        private static void CopyOtherInputsTo(Room room, OneFrameInputs from, OneFrameInputs to)
+        public static void CopyOtherInputsTo(Room room, OneFrameInputs from, OneFrameInputs to)
         {
             long myId = room.GetComponent<RoomClientUpdater>().MyId;
             foreach (var kv in from.Inputs)

+ 36 - 15
Unity/Assets/Scripts/Hotfix/Share/LockStep/RoomSystem.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.IO;
 
 namespace ET
@@ -6,17 +7,17 @@ namespace ET
     [FriendOf(typeof(Room))]
     public static class RoomSystem
     {
-        public static void Init(this Room self, Room2C_Start room2CStart)
+        public static void Init(this Room self, List<LockStepUnitInfo> unitInfos, long startTime)
         {
-            self.StartTime = room2CStart.StartTime;
+            self.StartTime = startTime;
             
             self.FixedTimeCounter = new FixedTimeCounter(self.StartTime, 0, LSConstValue.UpdateInterval);
 
-            LSWorld lsWorld = self.GetComponent<LSWorld>();
+            LSWorld lsWorld = self.LSWorld;
             lsWorld.AddComponent<LSUnitComponent>();
-            for (int i = 0; i < room2CStart.UnitInfo.Count; ++i)
+            for (int i = 0; i < unitInfos.Count; ++i)
             {
-                LockStepUnitInfo unitInfo = room2CStart.UnitInfo[i];
+                LockStepUnitInfo unitInfo = unitInfos[i];
                 LSUnitFactory.Init(lsWorld, unitInfo);
                 self.PlayerIds.Add(unitInfo.PlayerId);
             }
@@ -25,13 +26,17 @@ namespace ET
 
         public static void Update(this Room self, OneFrameInputs oneFrameInputs, int frame)
         {
-            LSWorld lsWorld = self.GetComponent<LSWorld>();
-            // 保存当前帧场景数据
-            self.FrameBuffer.SaveLSWorld(frame, lsWorld);
+            LSWorld lsWorld = self.LSWorld;
 
-            if (frame <= self.RealFrame) // 只有Real帧才保存录像数据
+            if (!self.IsReplay)
             {
-                self.SaveData(frame);
+                // 保存当前帧场景数据
+                self.SaveLSWorld(frame);
+
+                if (frame <= self.AuthorityFrame) // 只有AuthorityFrame帧才保存录像数据
+                {
+                    self.Record(frame);
+                }
             }
 
             // 设置输入到每个LSUnit身上
@@ -45,17 +50,33 @@ namespace ET
             
             lsWorld.Update();
         }
+        
+        public static LSWorld GetLSWorld(this Room self, int frame)
+        {
+            MemoryBuffer memoryBuffer = self.FrameBuffer.Snapshot(frame);
+            return MongoHelper.Deserialize(typeof (LSWorld), memoryBuffer) as LSWorld;
+        }
+
+        public static void SaveLSWorld(this Room self, int frame)
+        {
+            MemoryBuffer memoryBuffer = self.FrameBuffer.Snapshot(frame);
+            memoryBuffer.Seek(0, SeekOrigin.Begin);
+            memoryBuffer.SetLength(0);
+            
+            MongoHelper.Serialize(self.LSWorld, memoryBuffer);
+            memoryBuffer.Seek(0, SeekOrigin.Begin);
+        }
 
-        public static void SaveData(this Room self, int frame)
+        public static void Record(this Room self, int frame)
         {
-            OneFrameInputs oneFrameInputs = self.FrameBuffer[frame];
+            OneFrameInputs oneFrameInputs = self.FrameBuffer.FrameInputs(frame);
             OneFrameInputs saveInput = new();
             oneFrameInputs.CopyTo(saveInput);
-            self.SaveData.MessagesList.Add(saveInput);
+            self.Record.FrameInputs.Add(saveInput);
             if (frame % LSConstValue.SaveLSWorldFrameCount == 0)
             {
-                MemoryBuffer memoryBuffer = self.FrameBuffer.GetMemoryBuffer(frame);
-                self.SaveData.LSWorlds.Add(memoryBuffer.ToArray());   
+                MemoryBuffer memoryBuffer = self.FrameBuffer.Snapshot(frame);
+                self.Record.Snapshots.Add(memoryBuffer.ToArray());   
             }
         }
     }

+ 1 - 1
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewSystem.cs

@@ -62,7 +62,7 @@ namespace ET.Client
                 return unit;
             }
 
-            self.Unit = (self.Domain as Room).GetComponent<LSWorld>().GetComponent<LSUnitComponent>().GetChild<LSUnit>(self.Id);
+            self.Unit = (self.Domain as Room).LSWorld.GetComponent<LSUnitComponent>().GetChild<LSUnit>(self.Id);
             return self.Unit;
         }
     }

+ 7 - 0
Unity/Assets/Scripts/Model/Client/LockStep/ReplayUpdater.cs

@@ -0,0 +1,7 @@
+namespace ET.Client
+{
+    public class ReplayUpdater: Entity, IAwake<Record>, IUpdate
+    {
+        public Record Record;
+    }
+}

+ 1 - 1
Unity/Assets/Scripts/Model/Share/LockStep/SaveData.cs.meta → Unity/Assets/Scripts/Model/Client/LockStep/ReplayUpdater.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 1775219934ec64b409ed64cb2aab6fbd
+guid: b8bc2dea400744f949883533fcd4ffb5
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 19 - 38
Unity/Assets/Scripts/Model/Share/LockStep/FrameBuffer.cs

@@ -7,41 +7,38 @@ namespace ET
     public class FrameBuffer
     {
         public int MaxFrame { get; private set; }
-        private readonly List<OneFrameInputs> messageBuffer;
-        private readonly List<MemoryBuffer> dataBuffer;
+        private readonly List<OneFrameInputs> frameInputs;
+        private readonly List<MemoryBuffer> snapshots;
 
         public FrameBuffer(int capacity = LSConstValue.FrameCountPerSecond * 10)
         {
             this.MaxFrame = capacity - 1;
-            this.messageBuffer = new List<OneFrameInputs>(capacity);
-            this.dataBuffer = new List<MemoryBuffer>(capacity);
+            this.frameInputs = new List<OneFrameInputs>(capacity);
+            this.snapshots = new List<MemoryBuffer>(capacity);
             
-            for (int i = 0; i < this.dataBuffer.Capacity; ++i)
+            for (int i = 0; i < this.snapshots.Capacity; ++i)
             {
-                this.messageBuffer.Add(new OneFrameInputs());
+                this.frameInputs.Add(new OneFrameInputs());
                 MemoryBuffer memoryBuffer = new(10240);
                 memoryBuffer.SetLength(0);
                 memoryBuffer.Seek(0, SeekOrigin.Begin);
-                this.dataBuffer.Add(memoryBuffer);
+                this.snapshots.Add(memoryBuffer);
             }
         }
         
-        public OneFrameInputs this[int frame]
+        public OneFrameInputs FrameInputs(int frame)
         {
-            get
+            if (frame < 0)
             {
-                if (frame < 0)
-                {
-                    return null;
-                }
+                return null;
+            }
 
-                if (frame > this.MaxFrame)
-                {
-                    return null;
-                }
-                OneFrameInputs oneFrameInputs = this.messageBuffer[frame % this.messageBuffer.Capacity];
-                return oneFrameInputs;
+            if (frame > this.MaxFrame)
+            {
+                return null;
             }
+            OneFrameInputs oneFrameInputs = this.frameInputs[frame % this.frameInputs.Capacity];
+            return oneFrameInputs;
         }
 
         public void MoveForward(int frame)
@@ -55,11 +52,11 @@ namespace ET
             
             Log.Debug($"framebuffer move forward: {this.MaxFrame}");
             
-            OneFrameInputs oneFrameInputs = this[this.MaxFrame];
+            OneFrameInputs oneFrameInputs = this.FrameInputs(this.MaxFrame);
             oneFrameInputs.Inputs.Clear();
         }
 
-        public MemoryBuffer GetMemoryBuffer(int frame)
+        public MemoryBuffer Snapshot(int frame)
         {
             if (frame < 0)
             {
@@ -70,24 +67,8 @@ namespace ET
             {
                 return null;
             }
-            MemoryBuffer memoryBuffer = this.dataBuffer[frame % this.dataBuffer.Capacity];
+            MemoryBuffer memoryBuffer = this.snapshots[frame % this.snapshots.Capacity];
             return memoryBuffer;
         }
-
-        public LSWorld GetLSWorld(int frame)
-        {
-            MemoryBuffer memoryBuffer = GetMemoryBuffer(frame);
-            return MongoHelper.Deserialize(typeof (LSWorld), memoryBuffer) as LSWorld;
-        }
-
-        public void SaveLSWorld(int frame, LSWorld lsWorld)
-        {
-            MemoryBuffer memoryBuffer = this.dataBuffer[frame % this.dataBuffer.Capacity];
-            memoryBuffer.Seek(0, SeekOrigin.Begin);
-            memoryBuffer.SetLength(0);
-            
-            MongoHelper.Serialize(lsWorld, memoryBuffer);
-            memoryBuffer.Seek(0, SeekOrigin.Begin);
-        }
     }
 }

+ 18 - 0
Unity/Assets/Scripts/Model/Share/LockStep/Record.cs

@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using MemoryPack;
+
+namespace ET
+{
+    [MemoryPackable]
+    public partial class Record
+    {
+        [MemoryPackOrder(1)]
+        public List<LockStepUnitInfo> UnitInfos;
+        
+        [MemoryPackOrder(2)]
+        public List<OneFrameInputs> FrameInputs = new();
+        
+        [MemoryPackOrder(3)]
+        public List<byte[]> Snapshots = new();
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Model/Share/LockStep/Record.cs.meta

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

+ 0 - 31
Unity/Assets/Scripts/Model/Share/LockStep/RollbackHelper.cs

@@ -1,31 +0,0 @@
-namespace ET
-{
-    public static class RollbackHelper
-    {
-        public static void Rollback(Entity entity)
-        {
-            if (entity is LSEntity)
-            {
-                return;
-            }
-            
-            LSSington.Instance.Rollback(entity);
-            
-            if (entity.ComponentsCount() > 0)
-            {
-                foreach (var kv in entity.Components)
-                {
-                    Rollback(kv.Value);
-                }
-            }
-
-            if (entity.ChildrenCount() > 0)
-            {
-                foreach (var kv in entity.Children)
-                {
-                    Rollback(kv.Value);
-                }
-            }
-        }
-    }
-}

+ 26 - 3
Unity/Assets/Scripts/Model/Share/LockStep/Room.cs

@@ -1,5 +1,4 @@
 using System.Collections.Generic;
-using TrueSync;
 
 namespace ET
 {
@@ -12,16 +11,40 @@ namespace ET
         
         public long StartTime { get; set; }
 
+        // 帧缓存
         public FrameBuffer FrameBuffer { get; } = new();
 
+        // 计算fixedTime,fixedTime在客户端是动态调整的,会做时间膨胀缩放
         public FixedTimeCounter FixedTimeCounter { get; set; }
 
+        // 玩家id列表
         public List<long> PlayerIds { get; } = new(LSConstValue.MatchCount);
         
+        // 预测帧
         public int PredictionFrame { get; set; } = -1;
 
-        public int RealFrame { get; set; } = -1;
+        // 权威帧
+        public int AuthorityFrame { get; set; } = -1;
 
-        public SaveData SaveData = new();
+        // 存档
+        public Record Record = new();
+
+        private EntityRef<LSWorld> lsWorld;
+
+        // LSWorld做成child,可以有多个lsWorld,比如守望先锋有两个
+        public LSWorld LSWorld
+        {
+            get
+            {
+                return this.lsWorld;
+            }
+            set
+            {
+                this.AddChild(value);
+                this.lsWorld = value;
+            }
+        }
+
+        public bool IsReplay;
     }
 }

+ 0 - 15
Unity/Assets/Scripts/Model/Share/LockStep/SaveData.cs

@@ -1,15 +0,0 @@
-using System.Collections.Generic;
-using MemoryPack;
-
-namespace ET
-{
-    [MemoryPackable]
-    public partial class SaveData
-    {
-        [MemoryPackOrder(1)]
-        public List<OneFrameInputs> MessagesList = new();
-        
-        [MemoryPackOrder(2)]
-        public List<byte[]> LSWorlds = new();
-    }
-}