//int clearFrame = 0; //string clearReson = ""; //string Reson = ""; /// <summary> /// 从目标帧开始重新演算 /// </summary> /// <param name="frameCount"></param> public override void Recalc() { //Debug.Log("Recalc " + m_world.FrameCount); ConnectStatusComponent csc = m_world.GetSingletonComp <ConnectStatusComponent>(); // 先判断回退的帧预测的数据和本地数据是否一致,一致则不重计算 // 判断哪些帧是确定性数据,派发确定性 // 其余帧继续做预测 int frameCount = csc.confirmFrame; int aimCount = m_world.FrameCount; bool isAllMessage = true; bool isConflict = false; int allMessageFrame = frameCount; List <EntityBase> list = GetEntityList(); //增加目标帧 for (int i = aimCount + 1; ; i++) { if (list.Count == 0) { break; } for (int j = 0; j < list.Count; j++) { AddComp(list[j]); PlayerCommandRecordComponent tmp = list[j].GetComp <PlayerCommandRecordComponent>(ComponentType.PlayerCommandRecordComponent); isAllMessage &= tmp.GetAllMessage(i); } if (isAllMessage) { aimCount = i; } else { break; } } //先判断哪些帧不需要重计算 for (int i = frameCount + 1; i <= aimCount; i++) { isAllMessage = true; isConflict = false; for (int j = 0; j < list.Count; j++) { AddComp(list[j]); PlayerCommandRecordComponent tmp = list[j].GetComp <PlayerCommandRecordComponent>(ComponentType.PlayerCommandRecordComponent); isAllMessage &= tmp.GetAllMessage(i); isConflict |= tmp.GetConflict(i); //Debug.Log("GetAllMessage " + i + " -> " + tmp.GetAllMessage(i) + " isAllMessage " + isAllMessage); } if (isAllMessage) { if (!isConflict) { frameCount = i; allMessageFrame = i; m_world.IsCertainty = true; //派发确定性 m_world.eventSystem.DispatchCertainty(i); m_world.eventSystem.ClearCache(); //之后计算的事件作废 csc.confirmFrame = i; m_world.IsCertainty = false; //CheckCertaintyFrame(i); //Debug.Log("不用重计算 frame " + i); } else { //Debug.Log("需要重计算 frame " + i); m_world.eventSystem.ClearCache(); //之前计算的事件作废 allMessageFrame = i; break; } } else { break; } } //Debug.Log(" 重计算 Recalc frameCount -> " + frameCount + " aimCount -> " + aimCount); //如果没有新的确定帧出现,则不再重计算 if (frameCount == allMessageFrame) { //Debug.Log("没有新的确定帧出现,不再重计算"); return; } //回退到最后一个确定帧 m_world.RevertToFrame(frameCount); //目标帧之后的历史记录作废 m_world.ClearAfter(frameCount); m_world.IsRecalc = true; isAllMessage = true; for (int i = frameCount + 1; i <= aimCount; i++) { //确定性不能中断 if (isAllMessage) { for (int j = 0; j < list.Count; j++) { PlayerCommandRecordComponent tmp = list[j].GetComp <PlayerCommandRecordComponent>(ComponentType.PlayerCommandRecordComponent); isAllMessage &= tmp.GetAllMessage(i); } if (isAllMessage) { csc.confirmFrame = i; m_world.IsCertainty = true; } else { m_world.IsCertainty = false; } } if (m_world.IsCertainty) { //Debug.Log("确定帧 " + i);\ m_world.eventSystem.ClearCacheAt(i); } else { //Debug.Log("预测帧 " + i); } //重新演算 m_world.Recalc(i, WorldManager.IntervalTime); //服务器数据改动,服务器给的是确切数据,所以放在重计算之后 ExecuteServiceMessage(i); m_world.ClearRecordAt(i); //重新保存历史记录 m_world.Record(i); if (m_world.IsCertainty) { //Debug.Log("确定帧结束 " + i); } else { //Debug.Log("预测帧结束 " + i); } } m_world.EndRecalc(); //重计算的结果认定为最终结果,清除历史记录 m_world.ClearBefore(frameCount - 1); csc.ClearFrame = frameCount - 1; m_world.IsCertainty = false; m_world.IsRecalc = false; }