public ICommandResult Simulate(ICommandInput commandInput, Unit unit) { CommandInput_Move input_Move = commandInput as CommandInput_Move; UnitPathComponent unitPathComponent = unit.GetComponent <UnitPathComponent>(); PathfindingComponent pathfindingComponent = Game.Scene.GetComponent <PathfindingComponent>(); unitPathComponent.ABPath = ComponentFactory.Create <ABPathWrap, Vector3, Vector3>(unit.Position, input_Move.clickPos); pathfindingComponent.Search(unitPathComponent.ABPath); CommandResult_Move result_Move = CommandGCHelper.GetCommandResult <CommandResult_Move>(); result_Move.Path = unitPathComponent.ABPath.Result; // result_Move.dir = input_Move.moveDir;// 暂时就以输入的方向作为角色的方向 return(result_Move); }
//从哪一帧开始重新计算 public void ReCal(int startFrame) { for (int i = simulateFrame; i >= startFrame; i--) { if (cacheCommands.ContainsKey(i)) { foreach (var v in cacheCommands[i]) { switch (v.commandInput) { //移动的话,直接取最后一次的目标作为目标就好了. case CommandInput_Move input_Move: CommandResult_Move result_Move = simulaterComponent.commandSimulaters[input_Move.GetType()].Simulate(input_Move, unit) as CommandResult_Move; v.commandResult = result_Move; //直接拉扯 unit.GetComponent <CharacterMoveComponent>().MoveAsync(result_Move.Path).Coroutine(); break; } return; } } } }
public void FixedUpdate() { //TODO; 和上一次服务器确认帧相差多少之后,提示网络有问题 simulateFrame++; //先上传这一帧的操作,同时缓存操作,然后客户端自己模拟操作的结果 if (collectedNewInput) { collectedNewInput = false; cacheCommands[simulateFrame] = new List <Command>(); cacheCommands[simulateFrame].AddRange(currCommands.Values); currCommands.Clear(); foreach (var v in cacheCommands[simulateFrame]) { switch (v.commandInput) { case CommandInput_Move input_Move: CommandResult_Move result_Move = simulaterComponent.commandSimulaters[input_Move.GetType()].Simulate(input_Move, unit) as CommandResult_Move; v.commandResult = result_Move; //再预测这一帧的结果 unit.GetComponent <CharacterMoveComponent>().MoveAsync(result_Move.Path).Coroutine(); //单机模式不发送网络消息 if (!Game.Scene.GetComponent <GlobalConfigComponent>().networkPlayMode) { break; } Log.Debug("frame : " + simulateFrame + " 本地预测的路径: " + result_Move.Path.ListToString <Vector3>()); inputInfo_Move.Frame = simulateFrame; inputInfo_Move.AimPos = input_Move.clickPos.ToV3Info(); ETModel.Game.Scene.GetComponent <SessionComponent>().Session.Send(inputInfo_Move); break; case CommandInput_UseSkill input_UseSkill: CommandResult_UseSkill result_UseSkill = simulaterComponent.commandSimulaters[input_UseSkill.GetType()].Simulate(input_UseSkill, unit) as CommandResult_UseSkill; v.commandResult = result_UseSkill; if (!Game.Scene.GetComponent <GlobalConfigComponent>().networkPlayMode) { //单机的话本地直接做决定了 unit.GetComponent <ActiveSkillComponent>().tcs?.SetResult(result_UseSkill.success); break; } switch (input_UseSkill.bufferValue) { case BufferValue_Pos value_Pos: Input_UseSkill_Pos.Frame = simulateFrame; Input_UseSkill_Pos.SkillId = input_UseSkill.skillId; Input_UseSkill_Pos.PipelineSignal = input_UseSkill.pipelineSignal; Input_UseSkill_Pos.AimPos = value_Pos.aimPos.ToV3Info(); ETModel.Game.Scene.GetComponent <SessionComponent>().Session.Send(Input_UseSkill_Pos); break; case BufferValue_Dir value_Dir: Input_UseSkill_Dir.Frame = simulateFrame; Input_UseSkill_Dir.SkillId = input_UseSkill.skillId; Input_UseSkill_Dir.PipelineSignal = input_UseSkill.pipelineSignal; Input_UseSkill_Dir.AimDir = value_Dir.dir.ToV3Info(); ETModel.Game.Scene.GetComponent <SessionComponent>().Session.Send(Input_UseSkill_Dir); break; case BufferValue_TargetUnits value_TargetUnits: Input_UseSkill_Tar.Frame = simulateFrame; Input_UseSkill_Tar.SkillId = input_UseSkill.skillId; Input_UseSkill_Tar.PipelineSignal = input_UseSkill.pipelineSignal; Input_UseSkill_Tar.UnitId = value_TargetUnits.targets[0].Id; ETModel.Game.Scene.GetComponent <SessionComponent>().Session.Send(Input_UseSkill_Tar); break; default: break; } break; } } } }