void OnGUI()
    {
        if (ReplicatedEntityCollection.SampleHistory)
        {
            GUILayout.Label("Sampling ...");
            return;
        }

        var clientGameLoop = Game.GetGameLoop <ClientGameLoop>();

        if (clientGameLoop == null)
        {
            return;
        }
        var clientGameWorld = clientGameLoop.GetClientGameWorld();

        if (clientGameWorld == null)
        {
            return;
        }
        ReplicatedEntityModuleClient repEntityModule = clientGameWorld.ReplicatedEntityModule;

        if (repEntityModule == null)
        {
            return;
        }

        var netId = repEntityModule.GetNetIdFromEntityIndex(m_selectedColumnIndex);

        if (netId == -1)
        {
            return;
        }

        var repData = repEntityModule.GetReplicatedDataForNetId(netId);

        // TODO (mogensh) also show non predicted data
        if (!repEntityModule.IsPredicted(m_selectedColumnIndex))
        {
            GUILayout.Label("no predicted data");
            return;
        }

        var selectedTick     = repEntityModule.GetSampleTick(m_selectedRowIndex);
        var predictStartTick = repEntityModule.GetLastServerTick(m_selectedRowIndex) + 1;
        var predictCount     = selectedTick - predictStartTick + 1;

        GUILayout.BeginHorizontal();

        var entityName = "NetId:" + netId + " E(" + repData.entity.Index + ":" + repData.entity.Version + ")";
        var goName     = repData.gameObject != null ? "(" + repData.gameObject.name + ")" : "";

        GUILayout.Label("Entity:" + entityName + goName);
        GUILayout.Label("Predict:" + predictStartTick + " to: " + selectedTick + "(" + predictCount + ")");
        columnWidth = EditorGUILayout.IntField("Column width", columnWidth);

        GUILayout.FlexibleSpace();
        GUILayout.EndHorizontal();


        if (predictCount > 30)
        {
            GUILayout.Label("Predict count HIGHT!");
            return;
        }


        GUILayout.BeginHorizontal();

        // Property names
        var scrollPos = GUILayout.BeginScrollView(new Vector2(0, m_inspectorScrolllPosition.y));

        m_inspectorScrolllPosition.y = scrollPos.y;
        {
            GUILayout.BeginVertical(GUILayout.Width(200));
            GUILayout.Label("Properties:");
            int predictedHandlerCount = repData.predictedArray.Length;
            for (int i = 0; i < predictedHandlerCount; i++)
            {
                var sampleIndex    = repEntityModule.FindSampleIndexForTick(selectedTick);
                var predictedState = repData.predictedArray[i].GetPredictedState(sampleIndex, 0);
                DrawEntityFieldNames(repData.predictedArray[i].GetEntity(), predictedState);
            }

            GUILayout.Label("UserCommand:");
            UserCommand userCommand;
            repEntityModule.GetUserCommand(selectedTick, out userCommand);
            DrawObjectFieldNames(userCommand);

            GUILayout.EndVertical();
        }
        GUILayout.EndScrollView();

        m_inspectorScrolllPosition = GUILayout.BeginScrollView(m_inspectorScrolllPosition);
        GUILayout.BeginHorizontal();

        for (int i = predictCount - 1; i >= 0; i--)
        {
            int predictTick = selectedTick - i;
            GUILayout.BeginVertical();

            GUILayout.Label("Tick:" + predictTick, GUILayout.Width(columnWidth));
            int predictedHandlerCount = repData.predictedArray.Length;
            for (int j = 0; j < predictedHandlerCount; j++)
            {
                var sampleIndex    = repEntityModule.FindSampleIndexForTick(selectedTick);
                var predictedState = repData.predictedArray[j].GetPredictedState(sampleIndex, i);

                var bg = GUI.color;
                GUI.color = i == 0 ? Color.cyan : new Color(0.0f, 0.7f, 0.7f, 1f);
                DrawObjectFieldValues(predictedState);
                GUI.color = bg;
            }

            GUILayout.Label("UserCommand:");
            UserCommand userCommand;
            var         validUserCmd = repEntityModule.GetUserCommand(predictTick, out userCommand);
            if (validUserCmd)
            {
                DrawObjectFieldValues(userCommand);
            }


            GUILayout.EndVertical();
        }

        {
            GUILayout.BeginVertical();
            GUILayout.Label("ServerState:");
            int predictedHandlerCount = repData.predictedArray.Length;
            for (int i = 0; i < predictedHandlerCount; i++)
            {
                var serverState = repData.predictedArray[i].GetServerState(selectedTick);

                if (serverState == null)
                {
                    continue;
                }

                var sampleIndex = repEntityModule.FindSampleIndexForTick(selectedTick);
                var verified    = repData.predictedArray[i].VerifyPrediction(sampleIndex, selectedTick);

                var bg = GUI.color;
                GUI.color = verified ? Color.green : Color.red;
                DrawObjectFieldValues(serverState);
                GUI.color = bg;
            }
            GUILayout.EndVertical();
        }

        GUILayout.FlexibleSpace();
        GUILayout.EndHorizontal();
        GUILayout.EndScrollView();
        GUILayout.EndHorizontal();
    }
Пример #2
0
    void DrawStates()
    {
        var clientGameLoop = Game.GetGameLoop <ClientGameLoop>();

        if (clientGameLoop == null)
        {
            return;
        }
        var clientGameWorld = clientGameLoop.GetClientGameWorld();

        if (clientGameWorld == null)
        {
            return;
        }
        ReplicatedEntityModuleClient repEntityModule = clientGameWorld.ReplicatedEntityModule;

        if (repEntityModule == null)
        {
            return;
        }

        var sampleCount = repEntityModule.GetSampleCount();
        int entityCount = repEntityModule.GetEntityCount();


        if (ReplicatedEntityCollection.SampleHistory)
        {
            GUILayout.Label("Sampling ...");

            if (m_stopOnMispredict)
            {
                for (int iEntity = 0; iEntity < entityCount; iEntity++)
                {
                    for (int i = 0; i < sampleCount; i++)
                    {
                        int tick = repEntityModule.GetSampleTick(i);

                        var netId = repEntityModule.GetNetIdFromEntityIndex(iEntity);
                        if (netId == -1)
                        {
                            continue;
                        }

                        var repData = repEntityModule.GetReplicatedDataForNetId(netId);

                        var  sampleIndex     = repEntityModule.FindSampleIndexForTick(tick);
                        bool predictionValid = repData.VerifyPrediction(sampleIndex, tick);
                        if (!predictionValid)
                        {
                            ReplicatedEntityCollection.SampleHistory = false;
                            Repaint();
                        }
                    }
                }
            }

            return;
        }


        int tickWidth  = 120;
        int stateWidth = 100;

        // Handle arrow navigation
        Event e = Event.current;

        if (e.type == EventType.KeyDown)
        {
            bool repaint = false;
            if (e.keyCode == KeyCode.UpArrow && m_selectedRow > 0)
            {
                m_selectedRow--;
                repaint = true;
            }

            if (e.keyCode == KeyCode.DownArrow && m_selectedRow < sampleCount - 1)
            {
                m_selectedRow++;
                repaint = true;
            }

            if (e.keyCode == KeyCode.LeftArrow && m_selectedColumn > -1)
            {
                m_selectedColumn--;
                repaint = true;
            }

            if (e.keyCode == KeyCode.RightArrow && m_selectedColumn < entityCount - 1)
            {
                m_selectedColumn++;
                repaint = true;
            }

            if (repaint)
            {
                Repaint();
                UpdateInspector();
                EditorGUIUtility.ExitGUI();
            }
        }

        GUILayout.BeginVertical();

        // Headed
        GUILayout.BeginHorizontal();
        GUILayout.Label("Tick", GUILayout.Width(tickWidth));

        GUILayout.BeginScrollView(new Vector2(m_statesScrolllPosition.x, 0), GUIStyle.none, GUIStyle.none);
        GUILayout.BeginHorizontal();

        for (int iEntity = 0; iEntity < entityCount; iEntity++)
        {
            var netId = repEntityModule.GetNetIdFromEntityIndex(iEntity);
            if (netId == -1)
            {
                continue;
            }
            var repData = repEntityModule.GetReplicatedDataForNetId(netId);


            GUILayout.BeginVertical(GUILayout.Width(stateWidth));

            GUILayout.Label("Net id:" + netId, GUILayout.Width(stateWidth));

            var entityName = "Entity i:" + repData.entity.Index + " v:" + repData.entity.Version;
            GUILayout.Label(entityName, GUILayout.Width(stateWidth));
            var gameObjectName = repData.gameObject != null ? repData.gameObject.name : "";
            GUILayout.Label(gameObjectName, GUILayout.Width(stateWidth));
            GUILayout.EndVertical();
        }
        GUILayout.EndHorizontal();
        GUILayout.EndScrollView();

        GUILayout.EndHorizontal();

        // State grid
        GUILayout.BeginHorizontal();

        string[] stringRows = new string[sampleCount];

        // Ticks

        var scroll = GUILayout.BeginScrollView(new Vector2(0, m_statesScrolllPosition.y), GUILayout.Width(tickWidth));

        m_statesScrolllPosition.y = scroll.y;
        {
            for (int i = 0; i < sampleCount; i++)
            {
                int tick           = repEntityModule.GetSampleTick(i);
                int lastServerTIck = repEntityModule.GetLastServerTick(i);
                stringRows[i] = i + " " + tick.ToString() + " P:" + (tick - lastServerTIck);
            }
            GUILayout.SelectionGrid(-1, stringRows, 1);
        }
        GUILayout.EndScrollView();


        m_statesScrolllPosition = GUILayout.BeginScrollView(m_statesScrolllPosition);
        GUILayout.BeginHorizontal();

        // States
        for (int iEntity = 0; iEntity < entityCount; iEntity++)
        {
            bool isSelectedColumn = m_selectedColumn == iEntity;
            int  selectedIndex    = isSelectedColumn ? m_selectedRow : -1;


            for (int i = 0; i < sampleCount; i++)
            {
                int tick = repEntityModule.GetSampleTick(i);

                var netId = repEntityModule.GetNetIdFromEntityIndex(iEntity);
                if (netId == -1)
                {
                    continue;
                }
                var repData = repEntityModule.GetReplicatedDataForNetId(netId);

                var isPredicted = repEntityModule.IsPredicted(iEntity);
                var hasState    = repData.HasState(tick);

                if (isPredicted)
                {
                    var sampleIndex     = repEntityModule.FindSampleIndexForTick(tick);
                    var predictionValid = repData.VerifyPrediction(sampleIndex, tick);
                    stringRows[i] = !predictionValid ? "MISS" : hasState ? "P+S" : "P";
                }
                else
                {
                    stringRows[i] = hasState ? "S" : "";
                }
            }

            int newIndex = GUILayout.SelectionGrid(selectedIndex, stringRows, 1, GUILayout.Width(stateWidth));

            if (newIndex != selectedIndex)
            {
                m_selectedRow = newIndex;
                if (m_selectedColumn != iEntity)
                {
                    m_selectedColumn = iEntity;
                }

                UpdateInspector();
                Repaint();
            }
        }
        GUILayout.FlexibleSpace();
        GUILayout.EndHorizontal();
        GUILayout.EndScrollView();

        GUILayout.EndHorizontal();

        GUILayout.EndVertical();
    }