コード例 #1
0
    //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;
    }