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(); }
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(); }