public override void DrawInspector(IPlanVisualizer visualizer) { if (m_Plan.TryGetStateInfo(StateKey, out var stateInfo)) { base.DrawInspector(visualizer); EditorGUILayout.LabelField("Estimated Total Reward", $"{stateInfo.CumulativeRewardEstimate}", EditorStyles.whiteLabel); EditorGUILayout.LabelField("Subplan Is Complete", $"{stateInfo.SubplanIsComplete}", EditorStyles.whiteLabel); if (m_Plan.TryGetOptimalAction(StateKey, out var optimalActionKey)) { EditorGUILayout.LabelField("Best Action", m_PlanExecutor.GetActionName(optimalActionKey), EditorStyles.whiteLabel); } if (string.IsNullOrEmpty(m_CachedStateString)) { m_CachedStateString = m_Plan.GetStateData(StateKey)?.ToString(); } if (string.IsNullOrEmpty(m_CachedStateString)) // State may no longer exist but be selected as an override. { return; } if (!m_RootState || active) { s_ActionsGUIFoldout = EditorStyleHelper.DrawSubHeader(new GUIContent("Actions"), s_ActionsGUIFoldout); if (s_ActionsGUIFoldout) { using (new EditorGUI.IndentLevelScope()) { m_Plan.GetActions(StateKey, s_Actions); SortSuccessorActions(s_Actions, ref s_Successors, out _, out _); for (var i = 0; i < s_Successors.Count; i++) { var successor = s_Successors[i]; var actionKey = successor.ActionKey; if (m_Plan.TryGetActionInfo(StateKey, actionKey, out var actionInfo)) { var rect = EditorGUILayout.BeginHorizontal(); var stateActionKey = (StateKey, actionKey); bool toggle = i < visualizer.MaxChildrenNodes || visualizer.ForcedExpandedNodes.Contains(stateActionKey); if (i < visualizer.MaxChildrenNodes) { GUI.enabled = false; } EditorGUI.BeginChangeCheck(); toggle = GUI.Toggle(rect, toggle, string.Empty); if (EditorGUI.EndChangeCheck()) { if (toggle) { visualizer.ForcedExpandedNodes.Add(stateActionKey); } else { visualizer.ForcedExpandedNodes.Remove(stateActionKey); } } GUI.enabled = true; EditorGUILayout.LabelField(new GUIContent(m_PlanExecutor.GetActionName(actionKey)), new GUIContent($"{actionInfo.CumulativeRewardEstimate.Average:0.000}", $"{actionInfo.CumulativeRewardEstimate}"), EditorStyles.whiteLabel); EditorGUILayout.EndHorizontal(); using (new EditorGUI.IndentLevelScope()) { var parameters = m_PlanExecutor.GetActionParametersInfo(StateKey, actionKey); foreach (var param in parameters) { EditorGUILayout.LabelField(new GUIContent(param.ParameterName), new GUIContent(param.TraitObjectName, $"Object: {param.TraitObjectId}"), EditorStyles.whiteMiniLabel); } } } } } } } EditorGUILayout.Space(); s_StateGUIFoldout = EditorStyleHelper.DrawSubHeader(new GUIContent("State information"), s_StateGUIFoldout); var displayString = m_CachedStateString; if (s_StateGUIFoldout) { using (new EditorGUI.IndentLevelScope()) { EditorGUI.BeginChangeCheck(); s_StateFilter = EditorGUILayout.DelayedTextField(s_StateFilter); if (EditorGUI.EndChangeCheck()) { m_CachedFilterString = string.Empty; } if (!string.IsNullOrEmpty(s_StateFilter)) { if (string.IsNullOrEmpty(m_CachedFilterString)) { var stateStringSplit = m_CachedStateString.Split('\n'); var linesToInclude = new SortedSet <int>(); var lastEmptyLine = 0; for (var i = 0; i < stateStringSplit.Length; i++) { var stateStringLine = stateStringSplit[i]; if (string.IsNullOrWhiteSpace(stateStringLine)) { lastEmptyLine = i; } else if (stateStringLine.IndexOf(s_StateFilter, StringComparison.OrdinalIgnoreCase) >= 0) { var nextEmptyLine = i; while (!string.IsNullOrWhiteSpace(stateStringSplit[nextEmptyLine])) { nextEmptyLine++; if (nextEmptyLine == stateStringSplit.Length - 1) { break; } } for (var j = lastEmptyLine; j < nextEmptyLine; j++) { linesToInclude.Add(j); } } } var sb = new StringBuilder(); foreach (var line in linesToInclude) { sb.AppendLine(stateStringSplit[line]); } m_CachedFilterString = sb.ToString(); } displayString = m_CachedFilterString; } EditorGUILayout.LabelField(displayString, EditorStyleHelper.inspectorStyleLabel); } } if (GUILayout.Button("Copy State", EditorStyles.miniButton)) { displayString.CopyToClipboard(); } } }
public static GUIContent GetOperandDisplayContent(SerializedProperty operand, SerializedProperty @operator, IList <ParameterDefinition> parameters, float width, GUIStyle style) { var normalColor = EditorGUIUtility.isProSkin ? "white" : "black"; const string errorColor = "#EF2526"; var parameterProperty = operand.FindPropertyRelative("m_Parameter").stringValue; var traitDefinitionProperty = operand.FindPropertyRelative("m_Trait").objectReferenceValue as TraitDefinition; var enumProperty = operand.FindPropertyRelative("m_Enum").objectReferenceValue as EnumDefinition; var valueProperty = operand.FindPropertyRelative("m_Value").stringValue; var operandString = string.Empty; if (!string.IsNullOrEmpty(parameterProperty)) { // Check if the specified parameter exist bool validParameter = parameters.Any(p => p.Name == parameterProperty); operandString += EditorStyleHelper.RichText(parameterProperty, validParameter ? normalColor: errorColor, true); } if (traitDefinitionProperty != null) { bool validTrait = true; var parentParameter = parameters.FirstOrDefault(p => p.Name == parameterProperty); if (parentParameter != null) { // Check if the selected Parameter contains this trait validTrait = parentParameter.RequiredTraits.Any(t => t == traitDefinitionProperty); } var traitName = traitDefinitionProperty.name; operandString = AppendOperand(operandString, EditorStyleHelper.RichText(traitName, validTrait ? normalColor : errorColor)); var traitProperty = operand.GetValue <OperandValue>().TraitProperty; // Check if the value is a field of the selected Trait bool validTraitValue = traitProperty != default && traitProperty.PropertyId != -1; var displayedTrait = validTraitValue ? traitProperty.Name : "undefined"; operandString = AppendOperand(operandString, EditorStyleHelper.RichText(displayedTrait, validTraitValue ? normalColor : errorColor)); if (IsListOperand(operand) && IsListComparisonOperator(@operator) && !IsListAssignment(@operator)) { operandString = AppendOperand(operandString, "Length"); } } else { bool validValue = true; if (enumProperty != null) { operandString = EditorStyleHelper.RichText(enumProperty.name, normalColor, true); validValue = enumProperty.Elements.Any(p => p.Name == valueProperty); } if (!string.IsNullOrEmpty(valueProperty)) { foreach (var valuePart in valueProperty.Split('.')) { operandString = AppendOperand(operandString, EditorStyleHelper.RichText(valuePart, validValue ? normalColor : errorColor)); } } } if (Event.current.type == EventType.Repaint) { // Simplify display for parameter properties if the text doesn't fit Vector2 contentSize = style.CalcSize(new GUIContent(operandString)); if (contentSize.x > width) { var operandParts = operandString.Split('.'); if (operandParts.Length == 3) { operandString = $"{operandParts[0]}...{operandParts[2]}"; contentSize = style.CalcSize(new GUIContent(operandString)); if (contentSize.x > width) { operandString = $"...{operandParts[2]}"; } } else if (operandParts.Length == 2) { operandString = $"...{operandParts[1]}"; } } } return(new GUIContent(string.IsNullOrEmpty(operandString) ? "..." : operandString));; }