private void UpdateMultiFrame() { Singleton <GameLogic> .GetInstance().UpdateTails(); // 预测本次更新value次 int value = (int)((this.EndFrameNum - this.CurFrameNum) / (uint)this.nDriftFactor); // 本次尝试更新次数 this.tryCount = Mathf.Clamp(value, 1, 100); int i = this.tryCount; // 客户端游戏开始到现在的时间长度 long clientTime = (long)((double)(Time.realtimeSinceStartup - this.startFrameTime) * 1000.0); // 客户端与服务器的时差 long nDelayMs = clientTime - (long)((ulong)((this.SvrFrameIndex + 1u) * this.SvrFrameDelta)); // 本次平均网络延时 this.nJitterDelay = this.CalculateJitterDelay(nDelayMs); clientTime *= (long)this.frameSpeed; int num2 = 0; while (i > 0) { long num3 = (long)((ulong)this.CurFrameNum * (ulong)this.FrameDelta); this.nMultiFrameDelta = clientTime - num3; this.nMultiFrameDelta -= (long)this.nJitterDelay; if (this.nMultiFrameDelta < (long)((ulong)this.FrameDelta)) { break; } if (this.CurFrameNum >= this.EndFrameNum) { this.EndBlockWaitNum += 1u; this.m_maxEndBlockWaitNum = Mathf.Max(this.m_maxEndBlockWaitNum, (int)this.EndBlockWaitNum); break; } this.EndBlockWaitNum = 0u; this.CurFrameNum += 1u; num2++; this.LogicFrameTick += (ulong)this.FrameDelta; this.isCmdExecuting = true; while (this.commandQueue.get_Count() > 0) { IFrameCommand frameCommand = this.commandQueue.Peek(); uint num4 = (frameCommand.frameNum + this.SvrFrameLater) * this.KeyFrameRate; if (num4 > this.CurFrameNum) { break; } frameCommand.frameNum = num4; frameCommand = this.commandQueue.Dequeue(); frameCommand.ExecCommand(); } this.isCmdExecuting = false; Singleton <GameLogic> .GetInstance().UpdateLogic((int)this.FrameDelta, i == 1 && this.nMultiFrameDelta < (long)(2uL * (ulong)this.FrameDelta)); i--; } this.m_maxExcuteFrameOnce = Mathf.Max(this.m_maxExcuteFrameOnce, num2); }
private void UpdateMultiFrame() { Singleton <GameLogic> .GetInstance().UpdateTails(); int value = (int)((this.EndFrameNum - this.CurFrameNum) / (uint)this.nDriftFactor); this.tryCount = Mathf.Clamp(value, 1, 100); int i = this.tryCount; float realtimeSinceStartup = Time.realtimeSinceStartup; long num = (long)((double)(realtimeSinceStartup - this.startFrameTime) * 1000.0); long nDelayMs = num - (long)((ulong)((this.SvrFrameIndex + 1u) * this.SvrFrameDelta)); this.nJitterDelay = this.CalculateJitterDelay(nDelayMs); num *= (long)this.frameSpeed; while (i > 0) { long num2 = (long)((ulong)this.CurFrameNum * (ulong)this.FrameDelta); this.nMultiFrameDelta = num - num2; this.nMultiFrameDelta -= (long)this.nJitterDelay; if (this.nMultiFrameDelta >= (long)((ulong)this.FrameDelta)) { if (this.CurFrameNum >= this.EndFrameNum) { this.EndBlockWaitNum += 1u; i = 0; } else { this.EndBlockWaitNum = 0u; this.CurFrameNum += 1u; this.LogicFrameTick += (ulong)this.FrameDelta; this.isCmdExecuting = true; while (this.commandQueue.get_Count() > 0) { IFrameCommand frameCommand = this.commandQueue.Peek(); uint num3 = (frameCommand.frameNum + this.SvrFrameLater) * this.KeyFrameRate; if (num3 > this.CurFrameNum) { break; } frameCommand.frameNum = num3; frameCommand = this.commandQueue.Dequeue(); frameCommand.ExecCommand(); } this.isCmdExecuting = false; Singleton <GameLogic> .GetInstance().UpdateLogic((int)this.FrameDelta, i == 1 && this.nMultiFrameDelta < (long)(2uL * (ulong)this.FrameDelta)); i--; } } else { i = 0; } } }
private void UpdateSingleFrame() { Singleton <GameLogic> .GetInstance().UpdateTails(); long num = (long)(Time.deltaTime * 1000f); num = (long)Mathf.Clamp((int)num, 0, 100); this.CurFrameNum += 1u; this.LogicFrameTick += (ulong)num; this.isCmdExecuting = true; while (this.commandQueue.get_Count() > 0) { IFrameCommand frameCommand = this.commandQueue.Dequeue(); frameCommand.ExecCommand(); } this.isCmdExecuting = false; if (num > 0L) { Singleton <GameLogic> .GetInstance().UpdateLogic((int)num, false); } }
/// <summary> /// 该方法每个渲染帧会执行一次,但是会以逻辑帧间隔,经过平均延迟计算,触发逻辑帧的执行 /// </summary> /// <param name="bLocalTimeDriver"></param> private void UpdateMultiFrame(bool bLocalTimeDriver = false) { { MEObjDeliver e = ObjectCachePool.instance.Fetch <MEObjDeliver>(); e.opcode = (int)EObjDeliverOPCode.E_OP_UPDATE_TAILS_OF_GAME_LOGIC; Mercury.instance.Broadcast(EventTokenTable.et_framesynchr, this, e); } int drift = (int)((EndFrameNum - CurFrameNum) / (uint)nDriftFactor); tryCount = Mathf.Clamp(drift, 1, 100); int i = tryCount; float rt = Time.realtimeSinceStartup; if (bLocalTimeDriver) { rt = fLocalRunTime + startFrameTime; } //帧同步开始后经过了多少时间。nowtime 是渲染帧间隔,小于一个逻辑帧 long nowTime = (long)((rt - startFrameTime) * 1000f); long nDelayMs = nowTime - (long)((SvrFrameIndex + 1u) * SvrFrameDelta); //平均延迟(以30帧计算) int smoothDelay = CalculateJitterDelay(nDelayMs); nowTime *= (long)frameSpeed; while (i > 0) { long lastTime = (long)(CurFrameNum * FrameDelta); long deltaTime = nowTime - lastTime; deltaTime -= (long)smoothDelay; //这里是处理核心,如果 deltaTime 随着渲染帧的增长而增长,当他小于一个逻辑帧时,则不做任何处理,当他大于一个逻辑帧时,则触发一次逻辑帧处理 if (deltaTime >= (long)FrameDelta) { //假设一直没有收到新的逻辑帧,则每次都会执行到这里 if (CurFrameNum >= EndFrameNum) { EndBlockWaitNum += 1u; i = 0; } else { EndBlockWaitNum = 0u; CurFrameNum += 1u; LogicFrameTick += (ulong)FrameDelta; //先执行命令,再刷新游戏逻辑 while (commandQueue.Count > 0) { IFrameCommand frameCommand = commandQueue.Peek(); uint commandFrame = (frameCommand.frameNum + SvrFrameLater) * KeyFrameRate; if (commandFrame > CurFrameNum) { break; } frameCommand = commandQueue.Dequeue(); frameCommand.frameNum = commandFrame; frameCommand.ExecCommand(); AbstractSmartObj obj = (AbstractSmartObj)frameCommand; if (obj != null) { obj.Release(); } } if (!bEscape) { //通知刷新游戏逻辑层 MEObjDeliver e = ObjectCachePool.instance.Fetch <MEObjDeliver>(); e.args[0] = (int)FrameDelta; e.args[1] = i == 1 && deltaTime < (long)(2u * FrameDelta); //false; e.opcode = (int)EObjDeliverOPCode.E_OP_UPDATE_GAME_LOGIC; Mercury.instance.Broadcast(EventTokenTable.et_framesynchr, this, e); } i--; } } else { i = 0; } } }