public override void OnInspectorGUI() { EditorGUILayout.Separator(); serializedObject.Update(); var parametersProperty = serializedObject.FindProperty("m_Parameters"); parametersProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.parameters, parametersProperty.isExpanded); if (parametersProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); m_ParameterList.AdjustElementHeight(m_ParameterList.count == 0 ? 1 : 3); m_ParameterList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } var criteriaProperty = serializedObject.FindProperty("m_Criteria"); criteriaProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.criteria, criteriaProperty.isExpanded); if (criteriaProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); m_CriteriaList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } EditorGUILayout.EndFoldoutHeaderGroup(); var customRewards = serializedObject.FindProperty("m_CustomTerminalRewards"); if (customRewards != null) { customRewards.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.terminalRewards, customRewards.isExpanded); if (customRewards.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); EditorGUILayout.PropertyField(serializedObject.FindProperty("m_TerminalReward"), new GUIContent("Base Value")); GUILayout.Label(EditorStyleHelper.rewardModifiers); m_RewardModifiers.AdjustElementHeight(m_RewardModifiers.count == 0 ? 1 : 2); m_RewardModifiers.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } } serializedObject.ApplyModifiedProperties(); base.OnInspectorGUI(); }
public override void OnInspectorGUI() { var trait = (OldTraitDefinition)target; serializedObject.Update(); EditorGUILayout.Space(); m_FieldList.serializedProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.fields, m_FieldList.serializedProperty.isExpanded); if (m_FieldList.serializedProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); m_FieldList.AdjustElementHeight(m_FieldList.count == 0?1:3); m_FieldList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } m_ExpandAssetUsage = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.usages, m_ExpandAssetUsage); if (m_ExpandAssetUsage) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); EditorGUILayout.BeginVertical(GUI.skin.box); GUI.enabled = false; var used = IsTraitUsed(trait); GUI.enabled = true; if (!used) { GUILayout.Label("None", EditorStyles.miniLabel); } GUILayout.EndVertical(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } serializedObject.ApplyModifiedProperties(); base.OnInspectorGUI(); }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.Space(); m_EnumList.serializedProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.values, m_EnumList.serializedProperty.isExpanded); if (m_EnumList.serializedProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); m_EnumList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } serializedObject.ApplyModifiedProperties(); base.OnInspectorGUI(); }
public override void OnInspectorGUI() { serializedObject.Update(); var definition = serializedObject.FindProperty("m_ProblemDefinition"); if (!definition.objectReferenceValue) { AssignPlanGUI(definition); serializedObject.ApplyModifiedProperties(); return; } definition.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.settings, definition.isExpanded, AIPlannerPreferences.displayControllerAdvancedSettings, value => AIPlannerPreferences.displayControllerAdvancedSettings = value); if (definition.isExpanded) { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(definition); if (EditorGUI.EndChangeCheck()) { serializedObject.FindProperty("m_ActionExecuteInfos").ClearArray(); } EditorGUILayout.PropertyField(serializedObject.FindProperty("m_InitializeOnStart")); EditorGUILayout.PropertyField(serializedObject.FindProperty("m_AutoUpdate")); serializedObject.ApplyModifiedProperties(); if (AIPlannerPreferences.displayControllerAdvancedSettings) { EditorGUILayout.PropertyField(serializedObject.FindProperty("m_PlannerSettings")); EditorGUILayout.PropertyField(serializedObject.FindProperty("m_ExecutionSettings")); } EditorGUILayout.Space(); } if (definition.objectReferenceValue != null) { var actionMappingArray = serializedObject.FindProperty("m_ActionExecuteInfos"); actionMappingArray.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.actionExecution, actionMappingArray.isExpanded); if (actionMappingArray.isExpanded) { var plan = definition.objectReferenceValue as ProblemDefinition; if (plan != null && plan.ActionDefinitions != null) { // Remove actionInfo for actions not present in the plan for (int i = actionMappingArray.arraySize - 1; i >= 0; i--) { var actionInfoProperty = actionMappingArray.GetArrayElementAtIndex(i); var actionName = actionInfoProperty.FindPropertyRelative("m_ActionName").stringValue; if (plan.ActionDefinitions.FirstOrDefault(a => a.Name == actionName) == default) { actionMappingArray.DeleteArrayElementAtIndex(i); } } foreach (var actionDefinition in plan.ActionDefinitions) { if (actionDefinition == null) { continue; } EditorGUILayout.BeginVertical("Box"); EditorGUILayout.LabelField(actionDefinition.Name, EditorStyleHelper.namedObjectLabel); var actionMappingProperty = actionMappingArray.FindPropertyInArray(property => property.FindPropertyRelative("m_ActionName").stringValue == actionDefinition.Name); if (actionMappingProperty == null) { actionMappingProperty = actionMappingArray.InsertArrayElement(); actionMappingProperty.FindPropertyRelative("m_ActionName").stringValue = actionDefinition.Name; actionMappingProperty.FindPropertyRelative("m_Source").objectReferenceValue = null; } var sourceGameObjectProperty = actionMappingProperty.FindPropertyRelative("m_SourceGameObject"); if (sourceGameObjectProperty.objectReferenceValue == null) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.Space(); EditorGUILayout.HelpBox("Drag a GameObject to the field below (or use the selection icon) to match a planner action to a callback that will cause an effect in the world", MessageType.Info); sourceGameObjectProperty.objectReferenceValue = EditorGUILayout.ObjectField(GUIContent.none, sourceGameObjectProperty.objectReferenceValue, typeof(GameObject), true); EditorGUILayout.Space(); } } else { EditorGUI.BeginChangeCheck(); sourceGameObjectProperty.objectReferenceValue = EditorGUILayout.ObjectField(EditorStyleHelper.onActionStart, sourceGameObjectProperty.objectReferenceValue, typeof(GameObject), true); if (EditorGUI.EndChangeCheck()) { if (sourceGameObjectProperty.objectReferenceValue == null) { // Reset serialized data, when source object reference is removed actionMappingProperty.FindPropertyRelative("m_Source").objectReferenceValue = null; actionMappingProperty.FindPropertyRelative("m_Method").stringValue = String.Empty; actionMappingProperty.FindPropertyRelative("m_Arguments").ClearArray(); } } var sourceGameObject = sourceGameObjectProperty.objectReferenceValue as GameObject; if (sourceGameObject) { var components = sourceGameObject.GetComponents <MonoBehaviour>(); var sourceProperty = actionMappingProperty.FindPropertyRelative("m_Source"); using (new EditorGUI.IndentLevelScope()) { var component = sourceProperty.objectReferenceValue as Component; MethodInfo selectedMethod = null; var methods = components.Where(c => c != null) .SelectMany(c => c.GetType() .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public) .Where(m => !m.IsSpecialName) .Select(m => ((Component)c, m))).Prepend((default, default)).ToArray();;
internal static void PropertyField(Rect rect, IList <ParameterDefinition> parameters, SerializedProperty precondition, Type[] types) { const int operatorSize = 65; const int spacer = 5; var w = rect.width; var buttonSize = (w - operatorSize - 3 * spacer) / 2; rect.x += spacer; rect.y += EditorGUIUtility.standardVerticalSpacing; rect.width = buttonSize; var @operator = precondition.FindPropertyRelative("m_Operator"); switch (@operator.stringValue) { case nameof(Operation.SpecialOperators.Custom): rect.width = w - spacer; var customType = precondition.FindPropertyRelative("m_CustomOperatorType").stringValue; EditorStyleHelper.CustomMethodField(rect, customType, types); break; default: { var operandA = precondition.FindPropertyRelative("m_OperandA"); var operandB = precondition.FindPropertyRelative("m_OperandB"); TraitGUIUtility.DrawOperandSelectorField(rect, operandA, @operator, parameters, true, false, property => { TraitGUIUtility.ClearOperandProperty(operandB); }); var validLeftOperand = !string.IsNullOrEmpty(operandA.FindPropertyRelative("m_Parameter").stringValue); rect.x += buttonSize + spacer; rect.width = operatorSize; if (validLeftOperand) { var operators = GetComparisonOperators(operandA); var opIndex = EditorGUI.Popup(rect, Array.IndexOf(operators, @operator.stringValue), operators, EditorStyleHelper.listPopupStyleBold); @operator.stringValue = operators[Math.Max(0, opIndex)]; } else { // No operand available GUI.enabled = false; GUI.Button(rect, string.Empty, EditorStyleHelper.listPopupStyle); GUI.enabled = true; } rect.x += operatorSize + spacer; rect.width = buttonSize; if (validLeftOperand) { string unknownType = default; TraitGUIUtility.DrawOperandSelectorField(rect, operandB, @operator, parameters, TraitGUIUtility.GetOperandValuePropertyType(operandA, @operator, ref unknownType), unknownType); } else { // No operand available GUI.enabled = false; GUI.Button(rect, string.Empty, EditorStyleHelper.listPopupStyle); GUI.enabled = true; } } break; } }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.Space(); var parametersProperty = serializedObject.FindProperty("m_Parameters"); parametersProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.parameters, parametersProperty.isExpanded, AIPlannerPreferences.displayActionDefinitionAdvancedSettings, toggle => AIPlannerPreferences.displayActionDefinitionAdvancedSettings = toggle); if (parametersProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); if (m_ParameterList.count >= ActionKey.MaxLength) { EditorGUILayout.HelpBox(EditorStyleHelper.maxParametersReached); } m_ParameterList.AdjustElementHeight(m_ParameterList.count == 0 ? 1 : AIPlannerPreferences.displayActionDefinitionAdvancedSettings?4:3); m_ParameterList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } m_PreconditionList.serializedProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.preconditions, m_PreconditionList.serializedProperty.isExpanded); if (m_PreconditionList.serializedProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); m_PreconditionList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } m_ObjectCreatedList.serializedProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.effects, m_ObjectCreatedList.serializedProperty.isExpanded); if (m_ObjectCreatedList.serializedProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); GUILayout.Label(EditorStyleHelper.objectsCreated); m_ObjectCreatedList.AdjustElementHeight(m_ObjectCreatedList.count == 0 ? 1 : 2); m_ObjectCreatedList.DoLayoutList(); GUILayout.Label(EditorStyleHelper.objectsChanged); m_ObjectModifierList.DoLayoutList(); GUILayout.Label(EditorStyleHelper.objectsRemoved); m_ObjectRemovedList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } var customRewards = serializedObject.FindProperty("m_CustomRewards"); customRewards.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.rewards, customRewards.isExpanded); if (customRewards.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Reward"), new GUIContent("Base Value")); GUILayout.Label(EditorStyleHelper.rewardModifiers); m_RewardModifierList.AdjustElementHeight(m_RewardModifierList.count == 0 ? 1 : 2); m_RewardModifierList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } serializedObject.ApplyModifiedProperties(); base.OnInspectorGUI(); }
void DrawObjectModifierListElement(Rect rect, int index, bool isActive, bool isFocused) { var actionDefinition = (target as ActionDefinition); if (actionDefinition == null) { return; } const int operatorSize = 50; const int spacer = 5; var parameters = actionDefinition.Parameters.ToList(); var effectsParameters = actionDefinition.CreatedObjects.ToList(); parameters.AddRange(effectsParameters); var w = rect.width; var buttonSize = (w - operatorSize - 3 * spacer) / 2; rect.x += spacer; rect.y += EditorGUIUtility.standardVerticalSpacing; rect.width = buttonSize; var list = m_ObjectModifierList.serializedProperty; var effect = list.GetArrayElementAtIndex(index); var @operator = effect.FindPropertyRelative("m_Operator"); var operandA = effect.FindPropertyRelative("m_OperandA"); var operandB = effect.FindPropertyRelative("m_OperandB"); switch (@operator.stringValue) { case nameof(Operation.SpecialOperators.Add): case nameof(Operation.SpecialOperators.Remove): { TraitGUIUtility.DrawParameterSelectorField(rect, operandA.FindPropertyRelative("m_Parameter"), parameters); rect.x += buttonSize + spacer; rect.width = operatorSize; EditorGUI.LabelField(rect, (@operator.stringValue == nameof(Operation.SpecialOperators.Add))?"Add":"Remove", EditorStyleHelper.listValueStyle); rect.x += operatorSize + spacer; rect.width = buttonSize; var traitDefinitions = PlannerAssetDatabase.TraitDefinitions.ToArray(); var traitNames = traitDefinitions.Select(t => t?.name).ToArray(); var traitIndex = Array.IndexOf(traitDefinitions, operandB.FindPropertyRelative("m_Trait").objectReferenceValue as TraitDefinition); EditorGUI.BeginChangeCheck(); traitIndex = EditorGUI.Popup(rect, traitIndex, traitNames, EditorStyleHelper.listPopupStyle); if (EditorGUI.EndChangeCheck()) { TraitGUIUtility.ClearOperandProperty(operandB); operandB.FindPropertyRelative("m_Trait").objectReferenceValue = traitDefinitions[traitIndex]; } } break; case nameof(Operation.SpecialOperators.Custom): rect.width = w - spacer; var customType = effect.FindPropertyRelative("m_CustomOperatorType").stringValue; EditorStyleHelper.CustomMethodField(rect, customType, PlannerCustomTypeCache.ActionEffectTypes); break; default: { TraitGUIUtility.DrawOperandSelectorField(rect, operandA, null, parameters, modified => { TraitGUIUtility.ClearOperandProperty(operandB); }); var validLeftOperand = !string.IsNullOrEmpty(operandA.FindPropertyRelative("m_Parameter").stringValue); rect.x += buttonSize + spacer; rect.width = operatorSize; if (validLeftOperand) { var operators = GetAssignmentOperators(operandA); var opIndex = EditorGUI.Popup(rect, Array.IndexOf(operators, @operator.stringValue), operators, EditorStyleHelper.listPopupStyleBold); var operatorSelected = operators[Math.Max(0, opIndex)]; if (@operator.stringValue != operatorSelected) { if (TraitGUIUtility.IsListOperand(operandA) && TraitGUIUtility.IsListUnaryOperator(@operator)) { TraitGUIUtility.ClearOperandProperty(operandB); } @operator.stringValue = operatorSelected; } } else { // No operand available GUI.enabled = false; GUI.Button(rect, string.Empty, EditorStyleHelper.listPopupStyle); GUI.enabled = true; } var showRightOperand = !TraitGUIUtility.IsListOperand(operandA) || !TraitGUIUtility.IsListUnaryOperator(@operator); rect.x += operatorSize + spacer; rect.width = buttonSize; if (validLeftOperand && showRightOperand) { string unknownType = default; TraitGUIUtility.DrawOperandSelectorField(rect, operandB, @operator, parameters, TraitGUIUtility.GetOperandValuePropertyType(operandA, @operator, ref unknownType), unknownType); } else { // No operand available GUI.enabled = false; GUI.Button(rect, string.Empty, EditorStyleHelper.listPopupStyle); GUI.enabled = true; } } break; } }
internal static void PropertyField(Rect rect, IList<ParameterDefinition> target, SerializedProperty rewardElement, Type[] rewardTypes) { const int operatorSize = 60; const int spacer = 5; var w = rect.width; rect.width = operatorSize; rect.y += EditorGUIUtility.standardVerticalSpacing; var @operator = rewardElement.FindPropertyRelative("m_Operator"); var opIndex = EditorGUI.Popup(rect, Array.IndexOf(k_RewardOperators, @operator.stringValue), k_RewardOperators, EditorStyleHelper.listPopupStyle); if (k_RewardOperators.Length > 0) @operator.stringValue = k_RewardOperators[Math.Max(0, opIndex)]; rect.x += operatorSize; rect.width = w - operatorSize; rect.height = EditorGUIUtility.singleLineHeight; var methodName = rewardElement.FindPropertyRelative("m_Typename"); var customRewardFullNames = rewardTypes.Select(t => t.FullName).ToArray(); rect.x += spacer; EditorStyleHelper.CustomMethodField(rect, methodName.stringValue, rewardTypes); var customRewardIndex = Array.IndexOf(customRewardFullNames, methodName.stringValue); if (customRewardIndex >= 0) { rect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; var rewardType = rewardTypes[customRewardIndex]; var rewardParametersInfo = rewardType.GetMethod(k_RewardModifierMethodName)?.GetParameters(); if (rewardParametersInfo != null) { if (rewardParametersInfo[0].ParameterType.GetInterfaces().Contains(typeof(IStateData))) { GUI.Label(rect, "No parameters", EditorStyleHelper.italicGrayLabel); } else { var parameterProperties = rewardElement.FindPropertyRelative("m_Parameters"); var customParamCount = rewardParametersInfo.Length; if (parameterProperties.arraySize != customParamCount) { parameterProperties.arraySize = customParamCount; } if (customParamCount >= 0) { float paramWidth = rect.width / customParamCount; rect.width = paramWidth; for (var i = 0; i < customParamCount; i++) { var parameterType = rewardParametersInfo[i].ParameterType; TraitGUIUtility.DrawParameterSelectorField(rect, parameterProperties.GetArrayElementAtIndex(i), target, parameterType); rect.x += paramWidth; } } } } else { GUI.Label(rect, "Invalid reward type", EditorStyleHelper.errorTextField); } } }
public override void OnInspectorGUI() { serializedObject.Update(); m_ActionList.serializedProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.actions, m_ActionList.serializedProperty.isExpanded); if (m_ActionList.serializedProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); m_ActionList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } m_TerminationList.serializedProperty.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.terminations, m_TerminationList.serializedProperty.isExpanded); if (m_TerminationList.serializedProperty.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); m_TerminationList.DoLayoutList(); GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } var customCumulativeRewardEstimator = serializedObject.FindProperty("m_CustomCumulativeRewardEstimator"); customCumulativeRewardEstimator.isExpanded = EditorStyleHelper.DrawSubHeader(EditorStyleHelper.plannerSettings, customCumulativeRewardEstimator.isExpanded, AIPlannerPreferences.displayProblemDefinitionAdvancedSettings, value => AIPlannerPreferences.displayProblemDefinitionAdvancedSettings = value); if (customCumulativeRewardEstimator.isExpanded) { GUILayout.Space(EditorStyleHelper.subHeaderPaddingTop); var rewardEstimatorTypeNames = PlannerCustomTypeCache.CumulativeRewardEstimatorTypes.Select(t => t.FullName).Prepend(string.Empty).ToArray(); var rewardEstimatorTypeShortNames = PlannerCustomTypeCache.CumulativeRewardEstimatorTypes.Select(t => t.Name).Prepend(k_Default).ToArray(); var rewardEstimatorIndex = Array.IndexOf(rewardEstimatorTypeNames, customCumulativeRewardEstimator.stringValue); EditorGUI.BeginChangeCheck(); if (rewardEstimatorIndex == -1 && !string.IsNullOrEmpty(customCumulativeRewardEstimator.stringValue)) { GUI.backgroundColor = Color.red; rewardEstimatorTypeShortNames = rewardEstimatorTypeShortNames.Append($"Unknown type {customCumulativeRewardEstimator.stringValue}").ToArray(); rewardEstimatorIndex = rewardEstimatorTypeShortNames.Length - 1; } rewardEstimatorIndex = EditorGUILayout.Popup(EditorStyleHelper.cumulativeRewardEstimator, rewardEstimatorIndex, rewardEstimatorTypeShortNames); if (EditorGUI.EndChangeCheck()) { if (rewardEstimatorIndex < rewardEstimatorTypeNames.Length) { customCumulativeRewardEstimator.stringValue = rewardEstimatorTypeNames[rewardEstimatorIndex]; } } GUI.backgroundColor = Color.white; if (rewardEstimatorIndex == 0) { EditorGUILayout.BeginHorizontal(); using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.PrefixLabel("Bounds"); } var lowerEstimate = serializedObject.FindProperty("m_DefaultEstimateLower"); var averageEstimate = serializedObject.FindProperty("m_DefaultEstimateAverage"); var upperEstimate = serializedObject.FindProperty("m_DefaultEstimateUpper"); lowerEstimate.intValue = EditorGUILayout.IntField(lowerEstimate.intValue); averageEstimate.intValue = EditorGUILayout.IntField(averageEstimate.intValue); upperEstimate.intValue = EditorGUILayout.IntField(upperEstimate.intValue); EditorGUILayout.EndHorizontal(); } if (AIPlannerPreferences.displayProblemDefinitionAdvancedSettings) { var discountFactor = serializedObject.FindProperty("DiscountFactor"); EditorGUILayout.PropertyField(discountFactor); } GUILayout.Space(EditorStyleHelper.subHeaderPaddingBottom); } serializedObject.ApplyModifiedProperties(); base.OnInspectorGUI(); }