OneFrameInputsHandler.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. using System;
  2. namespace ET.Client
  3. {
  4. [MessageHandler(SceneType.LockStep)]
  5. public class OneFrameInputsHandler: MessageHandler<Scene, OneFrameInputs>
  6. {
  7. protected override async ETTask Run(Scene root, OneFrameInputs input)
  8. {
  9. using var _ = input ; // 方法结束时回收消息
  10. Fiber fiber = root.Fiber();
  11. Room room = root.GetComponent<Room>();
  12. fiber.Debug($"OneFrameInputs: {room.AuthorityFrame + 1} {input.ToJson()}");
  13. FrameBuffer frameBuffer = room.FrameBuffer;
  14. ++room.AuthorityFrame;
  15. // 服务端返回的消息比预测的还早
  16. if (room.AuthorityFrame > room.PredictionFrame)
  17. {
  18. OneFrameInputs authorityFrame = frameBuffer.FrameInputs(room.AuthorityFrame);
  19. input.CopyTo(authorityFrame);
  20. }
  21. else
  22. {
  23. // 服务端返回来的消息,跟预测消息对比
  24. OneFrameInputs predictionInput = frameBuffer.FrameInputs(room.AuthorityFrame);
  25. // 对比失败有两种可能,
  26. // 1是别人的输入预测失败,这种很正常,
  27. // 2 自己的输入对比失败,这种情况是自己发送的消息比服务器晚到了,服务器使用了你的上一次输入
  28. // 回滚重新预测的时候,自己的输入不用变化
  29. if (input != predictionInput)
  30. {
  31. fiber.Debug($"frame diff: {predictionInput} {input}");
  32. input.CopyTo(predictionInput);
  33. // 回滚到frameBuffer.AuthorityFrame
  34. fiber.Debug($"roll back start {room.AuthorityFrame}");
  35. LSClientHelper.Rollback(room, room.AuthorityFrame);
  36. fiber.Debug($"roll back finish {room.AuthorityFrame}");
  37. }
  38. else // 对比成功
  39. {
  40. room.Record(room.AuthorityFrame);
  41. room.SendHash(room.AuthorityFrame);
  42. }
  43. }
  44. await ETTask.CompletedTask;
  45. }
  46. }
  47. }