protected virtual void DrawMultiLineProperty(Rect rect, GUIContent label, SerializedProperty referenceProp, SerializedProperty valueProp, Flowchart flowchart, VariableInfoAttribute typeInfo) { const int popupWidth = 100; Rect controlRect = rect; Rect valueRect = controlRect; //valueRect.width = controlRect.width - 5; Rect popupRect = controlRect; popupRect.height = EditorGUIUtility.singleLineHeight; if (referenceProp.objectReferenceValue == null) { //EditorGUI.PropertyField(valueRect, valueProp, label); CustomVariableDrawerLookup.DrawCustomOrPropertyField(typeof(T), valueRect, valueProp, label); popupRect.x = rect.width - popupWidth + 5; popupRect.width = popupWidth; } else { popupRect = EditorGUI.PrefixLabel(rect, label); } EditorGUI.PropertyField(popupRect, referenceProp, GUIContent.none); }
protected virtual void DrawSingleLineProperty(Rect rect, GUIContent label, SerializedProperty referenceProp, SerializedProperty valueProp, Flowchart flowchart, VariableInfoAttribute typeInfo) { int popupWidth = Mathf.RoundToInt(EditorGUIUtility.singleLineHeight); const int popupGap = 5; //get out starting rect with intent honoured Rect controlRect = EditorGUI.PrefixLabel(rect, label); Rect valueRect = controlRect; valueRect.width = controlRect.width - popupWidth - popupGap; Rect popupRect = controlRect; //we are overriding much of the auto layout to cram this all on 1 line so zero the intend and restore it later var prevIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; if (referenceProp.objectReferenceValue == null) { CustomVariableDrawerLookup.DrawCustomOrPropertyField(typeof(T), valueRect, valueProp, GUIContent.none); popupRect.x += valueRect.width + popupGap; popupRect.width = popupWidth; } EditorGUI.PropertyField(popupRect, referenceProp, GUIContent.none); EditorGUI.indentLevel = prevIndent; }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Q: EditorGUI.BeginProperty ?? EditorGUI.BeginProperty(position, label, property); // The variable reference and data properties must follow the naming convention 'typeRef', 'typeVal' // 获得上面的VariableInfoAttribute标签 VariableInfoAttribute typeInfo = VariableEditor.GetVariableInfo(typeof(T)); if (typeInfo == null) { return; } string propNameBase = typeInfo.VariableType; propNameBase = Char.ToLowerInvariant(propNameBase[0]) + propNameBase.Substring(1); // 例如:获取 // BooleanVariable booleanRef; SerializedProperty referenceProp = property.FindPropertyRelative(propNameBase + "Ref"); // bool booleanVal; SerializedProperty valueProp = property.FindPropertyRelative(propNameBase + "Val"); if (referenceProp == null || valueProp == null) { return; } Command command = property.serializedObject.targetObject as Command; if (command == null) { return; } var flowchart = command.GetFlowchart() as Flowchart; if (flowchart == null) { return; } var origLabel = new GUIContent(label); if (EditorGUI.GetPropertyHeight(valueProp, label) > EditorGUIUtility.singleLineHeight) { DrawMultiLineProperty(position, origLabel, referenceProp, valueProp, flowchart); } else { DrawSingleLineProperty(position, origLabel, referenceProp, valueProp, flowchart); } EditorGUI.EndProperty(); }
public static VariableInfoAttribute GetVariableInfo(System.Type variableType) { object[] attributes = variableType.GetCustomAttributes(typeof(VariableInfoAttribute), false); foreach (object obj in attributes) { VariableInfoAttribute variableInfoAttr = obj as VariableInfoAttribute; if (variableInfoAttr != null) { return(variableInfoAttr); } } return(null); }
protected override void PrepareAllItems() { int i = 0; foreach (var item in VariableTypes) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(item); if (variableInfo != null) { allItems.Add(new FilteredListItem(i, (variableInfo.Category.Length > 0 ? variableInfo.Category + CATEGORY_CHAR : "") + variableInfo.VariableType)); } i++; } }
private void AddButton(ReorderableList list) { GenericMenu menu = new GenericMenu(); List <System.Type> types = FlowchartEditor.FindAllDerivedTypes <Variable>(); // Add variable types without a category foreach (var type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category != "") { continue; } AddVariableInfo addVariableInfo = new AddVariableInfo(); addVariableInfo.flowchart = TargetFlowchart; addVariableInfo.variableType = type; GUIContent typeName = new GUIContent(variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, addVariableInfo); } // Add types with a category foreach (var type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category == "") { continue; } AddVariableInfo info = new AddVariableInfo(); info.flowchart = TargetFlowchart; info.variableType = type; GUIContent typeName = new GUIContent(variableInfo.Category + "/" + variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, info); } menu.ShowAsContext(); }
/// <summary> /// Class constructor. /// <param name="target">The target object (node, variable or generic object).</param> /// <param name="serializedNode">The target serialized node.</param> /// <param name="path">The property path.</param> /// <param name="type">The type of the property.</param> /// <param name="propertyType">The property type.</param> /// <param name="array">The array that the element belongs to.</param> /// <param name="index">The element index.</param> /// <param name="variableInfo">A variable info if the serialized property is a variable; null otherwise.</param> /// </summary> public SerializedArrayElement(object target, SerializedNode serializedNode, string path, System.Type type, NodePropertyType propertyType, Array array, int index, VariableInfoAttribute variableInfo) : base(target, serializedNode, path, type, propertyType) { m_Array = array; m_Index = index; m_VariableInfo = variableInfo; this.label = "Element " + index.ToString(); // Its a variable type? if (propertyType == NodePropertyType.Variable) { // Update label this.tooltip = (type.Name + ": " + this.tooltip).Replace("Var", string.Empty); // Set concreteVariable var variable = m_Array.GetValue(m_Index) as BehaviourMachine.Variable; System.Type variableType = variable != null?variable.GetType() : null; m_IsConcreteVariable = variableType != null && TypeUtility.GetConcreteType(variableType) == variableType; } }
protected override void PrepareAllItems() { int i = 0; foreach (var item in VariableTypes) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(item); if (variableInfo != null) { var obsAttr = item.GetCustomAttribute <System.ObsoleteAttribute>(); var fliStr = (variableInfo.Category.Length > 0 ? variableInfo.Category + CATEGORY_CHAR : "") + (obsAttr != null ? FungusConstants.UIPrefixForDeprecated_RichText : "") + variableInfo.VariableType; allItems.Add(new FilteredListItem(i, fliStr)); } i++; } }
static protected void DoOlderMenu(Flowchart flowchart) { GenericMenu menu = new GenericMenu(); // Add variable types without a category foreach (var type in VariableTypes) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category != "") { continue; } GUIContent typeName = new GUIContent(variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, type); } // Add types with a category foreach (var type in VariableTypes) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category == "") { continue; } GUIContent typeName = new GUIContent(variableInfo.Category + CATEGORY_CHAR + variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, type); } menu.ShowAsContext(); }
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { VariableInfoAttribute typeInfo = VariableEditor.GetVariableInfo(typeof(T)); if (typeInfo == null) { return(EditorGUIUtility.singleLineHeight); } string propNameBase = typeInfo.VariableType; propNameBase = Char.ToLowerInvariant(propNameBase[0]) + propNameBase.Substring(1); SerializedProperty referenceProp = property.FindPropertyRelative(propNameBase + "Ref"); if (referenceProp.objectReferenceValue != null) { return(EditorGUIUtility.singleLineHeight); } SerializedProperty valueProp = property.FindPropertyRelative(propNameBase + "Val"); return(EditorGUI.GetPropertyHeight(valueProp, label)); }
public static void VariableDrawProperty(Variable variable, Rect rect, SerializedProperty valueProp, VariableInfoAttribute info) { if (valueProp == null) { EditorGUI.LabelField(rect, "N/A"); } else if (info.IsPreviewedOnly) { EditorGUI.LabelField(rect, variable.ToString()); } else { CustomVariableDrawerLookup.DrawCustomOrPropertyField(variable.GetType(), rect, valueProp, GUIContent.none); } }
public void DrawItem(Rect position, int index, bool selected, bool focused) { Variable variable = GetVarAt(index);// this[index].objectReferenceValue as Variable; if (variable == null) { return; } if (Event.current.type == EventType.ContextClick && position.Contains(Event.current.mousePosition)) { DoRightClickMenu(index); } for (int i = 0; i < 4; ++i) { itemRects[i] = position; itemRects[i].width = itemWidths[i] - 5; for (int j = 0; j < i; ++j) { itemRects[i].x += itemWidths[j]; } } var varType = variable.GetType(); VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(varType); if (variableInfo == null) { return; } var flowchart = TargetFlowchart; if (flowchart == null) { return; } // Highlight if an active or selected command is referencing this variable bool highlight = false; if (flowchart.SelectedBlock != null) { if (Application.isPlaying && flowchart.SelectedBlock.IsExecuting()) { highlight = flowchart.SelectedBlock.ActiveCommand.IsVariableReferenced(variable); } else if (!Application.isPlaying && flowchart.SelectedCommands.Count > 0) { foreach (Command selectedCommand in flowchart.SelectedCommands) { if (selectedCommand == null) { continue; } if (selectedCommand.IsVariableReferenced(variable)) { highlight = true; break; } } } } if (highlight) { GUI.backgroundColor = Color.green; GUI.Box(position, ""); } string key = variable.Key; VariableScope scope = variable.Scope; // To access properties in a monobehavior, you have to new a SerializedObject // http://answers.unity3d.com/questions/629803/findrelativeproperty-never-worked-for-me-how-does.html SerializedObject variableObject = new SerializedObject(variable); variableObject.Update(); var obsAttr = varType.GetCustomAttribute <System.ObsoleteAttribute>(); if (obsAttr != null) { var existingGUICol = GUI.color; GUI.color = Color.yellow; GUI.Label(itemRects[0], FungusConstants.UIPrefixForDeprecated + variableInfo.VariableType); GUI.color = existingGUICol; } else { GUI.Label(itemRects[0], variableInfo.VariableType); } SerializedProperty keyProp = variableObject.FindProperty("key"); SerializedProperty defaultProp = variableObject.FindProperty("value"); SerializedProperty scopeProp = variableObject.FindProperty("scope"); EditorGUI.BeginChangeCheck(); key = EditorGUI.TextField(itemRects[1], variable.Key); if (EditorGUI.EndChangeCheck()) { keyProp.stringValue = flowchart.GetUniqueVariableKey(key, variable); } bool isGlobal = scopeProp.enumValueIndex == (int)VariableScope.Global; var prevEnabled = GUI.enabled; if (isGlobal && Application.isPlaying) { var res = FungusManager.Instance.GlobalVariables.GetVariable(keyProp.stringValue); if (res != null) { SerializedObject globalValue = new SerializedObject(res); var globalValProp = globalValue.FindProperty("value"); GUI.enabled = false; defaultProp = globalValProp; } } //variable.DrawProperty(rects[2], defaultProp, variableInfo); VariableDrawProperty(variable, itemRects[2], defaultProp, variableInfo); GUI.enabled = prevEnabled; scope = (VariableScope)EditorGUI.EnumPopup(itemRects[3], variable.Scope); scopeProp.enumValueIndex = (int)scope; variableObject.ApplyModifiedProperties(); GUI.backgroundColor = Color.white; }
public void DrawItem(Rect position, int index) { Variable variable = this[index].objectReferenceValue as Variable; if (variable == null) { return; } int width = widthOfList; int totalRatio = DefaultWidth; float[] widths = { (80.0f / totalRatio) * width, (100.0f / totalRatio) * width, (140.0f / totalRatio) * width, (60.0f / totalRatio) * width }; Rect[] rects = new Rect[4]; for (int i = 0; i < 4; ++i) { rects[i] = position; rects[i].width = widths[i] - 5; for (int j = 0; j < i; ++j) { rects[i].x += widths[j]; } } VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(variable.GetType()); if (variableInfo == null) { return; } var flowchart = FlowchartWindow.GetFlowchart(); if (flowchart == null) { return; } // Highlight if an active or selected command is referencing this variable bool highlight = false; if (flowchart.SelectedBlock != null) { if (Application.isPlaying && flowchart.SelectedBlock.IsExecuting()) { highlight = flowchart.SelectedBlock.ActiveCommand.HasReference(variable); } else if (!Application.isPlaying && flowchart.SelectedCommands.Count > 0) { foreach (Command selectedCommand in flowchart.SelectedCommands) { if (selectedCommand == null) { continue; } if (selectedCommand.HasReference(variable)) { highlight = true; break; } } } } if (highlight) { GUI.backgroundColor = Color.green; GUI.Box(position, ""); } string key = variable.Key; VariableScope scope = variable.Scope; // To access properties in a monobehavior, you have to new a SerializedObject // http://answers.unity3d.com/questions/629803/findrelativeproperty-never-worked-for-me-how-does.html SerializedObject variableObject = new SerializedObject(this[index].objectReferenceValue); variableObject.Update(); GUI.Label(rects[0], variableInfo.VariableType); key = EditorGUI.TextField(rects[1], variable.Key); SerializedProperty keyProp = variableObject.FindProperty("key"); SerializedProperty defaultProp = variableObject.FindProperty("value"); SerializedProperty scopeProp = variableObject.FindProperty("scope"); keyProp.stringValue = flowchart.GetUniqueVariableKey(key, variable); bool isGlobal = scopeProp.enumValueIndex == (int)VariableScope.Global; if (isGlobal && Application.isPlaying) { var res = FungusManager.Instance.GlobalVariables.GetVariable(keyProp.stringValue); if (res != null) { SerializedObject globalValue = new SerializedObject(res); var globalValProp = globalValue.FindProperty("value"); var prevEnabled = GUI.enabled; GUI.enabled = false; EditorGUI.PropertyField(rects[2], globalValProp, new GUIContent("")); GUI.enabled = prevEnabled; } } else { EditorGUI.PropertyField(rects[2], defaultProp, new GUIContent("")); } scope = (VariableScope)EditorGUI.EnumPopup(rects[3], variable.Scope); scopeProp.enumValueIndex = (int)scope; variableObject.ApplyModifiedProperties(); GUI.backgroundColor = Color.white; }
public virtual void DrawVariablesGUI() { serializedObject.Update(); var t = target as Flowchart; if (t.Variables.Count == 0) { t.VariablesExpanded = true; } if (!t.VariablesExpanded) { if (GUILayout.Button("Variables (" + t.Variables.Count + ")", GUILayout.Height(24))) { t.VariablesExpanded = true; } // Draw disclosure triangle Rect lastRect = GUILayoutUtility.GetLastRect(); lastRect.x += 5; lastRect.y += 5; EditorGUI.Foldout(lastRect, false, ""); } else { Rect listRect = new Rect(); if (t.Variables.Count > 0) { // Remove any null variables from the list // Can sometimes happen when upgrading to a new version of Fungus (if .meta GUID changes for a variable class) for (int i = t.Variables.Count - 1; i >= 0; i--) { if (t.Variables[i] == null) { t.Variables.RemoveAt(i); } } ReorderableListGUI.Title("Variables"); VariableListAdaptor adaptor = new VariableListAdaptor(variablesProp, 0); ReorderableListFlags flags = ReorderableListFlags.DisableContextMenu | ReorderableListFlags.HideAddButton; ReorderableListControl.DrawControlFromState(adaptor, null, flags); listRect = GUILayoutUtility.GetLastRect(); } else { GUILayoutUtility.GetRect(300, 24); listRect = GUILayoutUtility.GetLastRect(); listRect.y += 20; } float plusWidth = 32; float plusHeight = 24; Rect buttonRect = listRect; float buttonHeight = 24; buttonRect.x = 4; buttonRect.y -= buttonHeight - 1; buttonRect.height = buttonHeight; if (!Application.isPlaying) { buttonRect.width -= 30; } if (GUI.Button(buttonRect, "Variables")) { t.VariablesExpanded = false; } // Draw disclosure triangle Rect lastRect = buttonRect; lastRect.x += 5; lastRect.y += 5; EditorGUI.Foldout(lastRect, true, ""); Rect plusRect = listRect; plusRect.x += plusRect.width - plusWidth; plusRect.y -= plusHeight - 1; plusRect.width = plusWidth; plusRect.height = plusHeight; if (!Application.isPlaying && GUI.Button(plusRect, addTexture)) { GenericMenu menu = new GenericMenu(); List <System.Type> types = FindAllDerivedTypes <Variable>(); // Add variable types without a category foreach (var type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category != "") { continue; } AddVariableInfo addVariableInfo = new AddVariableInfo(); addVariableInfo.flowchart = t; addVariableInfo.variableType = type; GUIContent typeName = new GUIContent(variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, addVariableInfo); } // Add types with a category foreach (var type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category == "") { continue; } AddVariableInfo info = new AddVariableInfo(); info.flowchart = t; info.variableType = type; GUIContent typeName = new GUIContent(variableInfo.Category + "/" + variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, info); } menu.ShowAsContext(); } } serializedObject.ApplyModifiedProperties(); }
/// <summary> /// Returns a set of serialized properties in an array. /// <param name="serializedNode">The target serialized node.</param> /// <param name="target">The target object (node, variable or generic object).</param> /// <param name="targetArray">The target array.</param> /// <param name="type">The elements type in the array.</param> /// <param name="currentPath">The property path of the target array.</param> /// <param name="variableInfo">The variable info in the array or null.</param> /// <param name="propertyAttr">The property attribute in the array.</param> /// <returns>The serialized properties in the array.</returns> /// </summary> static SerializedNodeProperty[] GetPropertiesData(SerializedNode serializedNode, object target, Array targetArray, Type type, string currentPath, VariableInfoAttribute variableInfo, PropertyAttribute propertyAttr) { // Create the property data list var propertyData = new List <SerializedNodeProperty>(); // Get the property type var propertyType = SerializedNode.GetPropertyType(type); if (targetArray != null) { // Variable? if (propertyType == NodePropertyType.Variable) { for (int i = 0; i < targetArray.Length; i++) { // Get the field value object elementValue = targetArray.GetValue(i); // Create the variable data var variableData = new SerializedArrayElement(target, serializedNode, currentPath + "data[" + i.ToString() + "]", type, propertyType, targetArray, i, variableInfo); // Create the variable children SerializedNodeProperty[] children = SerializedNode.GetPropertiesData(serializedNode, elementValue, elementValue != null ? elementValue.GetType() : type, variableData.path + "."); // Create the property drawer for the "Value" child property if (propertyAttr != null && variableData.isConcreteVariable) { foreach (var child in children) { // It is the "Value" property? if (child.label == "Value") { child.customDrawer = NodePropertyDrawer.GetDrawer(propertyAttr); } } } // Set children variableData.SetChildren(children); // Add the variable data to the list propertyData.Add(variableData); } } // Array? else if (propertyType == NodePropertyType.Array) { for (int i = 0; i < targetArray.Length; i++) { // Create the current property data var currentPropertyData = new SerializedArrayElement(target, serializedNode, currentPath + "data[" + i.ToString() + "]", type, propertyType, targetArray, i, variableInfo); // Get the array value var array = targetArray.GetValue(i) as Array; // Get array element type var elementType = type.GetElementType(); // Create the array children list var childrenList = new List <SerializedNodeProperty>(); // Create the array size childrenList.Add(new SerializedArraySize(target, serializedNode, currentPropertyData.path + ".size", currentPropertyData, array, elementType)); // Create array children childrenList.AddRange(SerializedNode.GetPropertiesData(serializedNode, target, array, elementType, currentPropertyData.path + ".", variableInfo, propertyAttr)); // Set array data children currentPropertyData.SetChildren(childrenList.ToArray()); // Add to list propertyData.Add(currentPropertyData); } } else { for (int i = 0; i < targetArray.Length; i++) { // Create the current property data var currentPropertyData = new SerializedArrayElement(target, serializedNode, currentPath + "data[" + i.ToString() + "]", type, propertyType, targetArray, i, variableInfo); // Try to get a property drawer if (propertyAttr != null) { currentPropertyData.customDrawer = NodePropertyDrawer.GetDrawer(propertyAttr); } // Add to list propertyData.Add(currentPropertyData); } } } return(propertyData.ToArray()); }
/// <summary> /// Draws a variable field on the GUI. /// <param name= "guiContent">The GUI content to draw the property.</param> /// <param name= "property">The variable property.</param> /// <param name= "node">The node that owns the variable to be drawn.</param> /// </summary> public static void VariableField(GUIContent guiContent, SerializedNodeProperty property, ActionNode node) { var variable = property.value as Variable; var isNone = variable == null || variable.isNone; var isConstant = !isNone && variable.isConstant; VariableInfoAttribute variableInfo = property.variableInfo; string popupName = string.Empty; Texture popupTexture = null; #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 var rect = GUILayoutUtility.GetRect(guiContent, EditorStyles.popup); #else var rect = EditorGUILayout.GetControlRect(); #endif var id = GUIUtility.GetControlID(FocusType.Keyboard); // Set label color if (isNone && variableInfo.requiredField) { EditorStyles.label.normal.textColor = Color.red; } // Draw label rect = EditorGUI.PrefixLabel(rect, id, guiContent); // Restore label color EditorStyles.label.normal.textColor = s_Styles.labelTextColor; if (isNone) { popupName = variableInfo.nullLabel; popupTexture = s_Styles.noneTexture; } else if (isConstant) { if (property.isConcreteVariable) { popupName = "Constant"; popupTexture = s_Styles.constantTexture; } else { popupName = variable.GetType().Name; popupTexture = IconUtility.GetIcon(variable.GetType()); } } else { popupName = variable.name; // Its a global var? popupTexture = variable.isGlobal ? s_Styles.globalBlackboardTexture : popupTexture = s_Styles.blackboardTexture;; } // Popup button if (GUIHelper.EditorButton(rect, id, new GUIContent(popupName, popupTexture), s_Styles.popup)) { // Set keyboard focus to the label GUIUtility.keyboardControl = id; // Create the menu and the list of unique names var menu = new GenericMenu(); var names = new List <string>() { }; // None names.Add(variableInfo.nullLabel); menu.AddItem(new GUIContent(variableInfo.nullLabel), isNone, delegate { if (isConstant && property.isConcreteVariable) { variable.SetAsNone(); property.ValueChanged(); } else if (!isNone) { object noneVariable; if (property.type == typeof(GameObjectVar)) { noneVariable = Activator.CreateInstance(TypeUtility.GetConcreteType(property.type), new object[] { node.self }); } else if (property.type.IsAbstract) { noneVariable = Activator.CreateInstance(TypeUtility.GetConcreteType(property.type)); } else { noneVariable = Activator.CreateInstance(property.type); } property.value = noneVariable; } }); // Create the anonymous function to set constants GenericMenu.MenuFunction2 createConstant = delegate(object userData) { // Get the desired variable type var type = userData as System.Type; // its not a constant or its an "ex global" var (an ex global var does not have a GlobalBlackboard)? if (variable == null || variable.isInvalid || property.type == typeof(BehaviourMachine.Variable)) { // Create a constant Variable newVariable; if (property.type == typeof(GameObjectVar)) { newVariable = Activator.CreateInstance(TypeUtility.GetConcreteType(type), new object[] { node.self }) as Variable; } else if (type.IsAbstract) { newVariable = Activator.CreateInstance(TypeUtility.GetConcreteType(type)) as Variable; } else { newVariable = Activator.CreateInstance(type) as Variable; } newVariable.SetAsConstant(); property.value = newVariable; property.ValueChanged(); } else if (isNone) { variable.SetAsConstant(); property.ValueChanged(); } else if ((isConstant && !property.isConcreteVariable) || !isConstant) { // Create a concrete variable type and update the field value! Variable newVariable; if (type == typeof(GameObjectVar)) { newVariable = Activator.CreateInstance(TypeUtility.GetConcreteType(type), new object[] { node.self }) as Variable; } else if (type.IsAbstract) { newVariable = Activator.CreateInstance(TypeUtility.GetConcreteType(type)) as Variable; } else { newVariable = Activator.CreateInstance(type) as Variable; } newVariable.SetAsConstant(); property.value = newVariable; } }; // Add the Constant name to the list names.Add("Constant"); // Can be constant? if (variableInfo.canBeConstant && property.type != typeof(BehaviourMachine.FsmEvent) && property.type != typeof(BehaviourMachine.DynamicList)) { if (property.type != typeof(BehaviourMachine.Variable)) { menu.AddItem(new GUIContent("Constant"), isConstant && property.isConcreteVariable, createConstant, property.type); } else { bool variableNotNull = variable != null; // If its a Variable type then add options for all concrete variables if (!variableInfo.fixedType) { menu.AddItem(new GUIContent("Constant/Variable"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.Variable), createConstant, typeof(BehaviourMachine.Variable)); menu.AddItem(new GUIContent("Constant/FloatVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteFloatVar), createConstant, typeof(BehaviourMachine.ConcreteFloatVar)); menu.AddItem(new GUIContent("Constant/IntVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteIntVar), createConstant, typeof(BehaviourMachine.ConcreteIntVar)); menu.AddItem(new GUIContent("Constant/BoolVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteBoolVar), createConstant, typeof(BehaviourMachine.ConcreteBoolVar)); menu.AddItem(new GUIContent("Constant/StringVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteStringVar), createConstant, typeof(BehaviourMachine.ConcreteStringVar)); menu.AddItem(new GUIContent("Constant/Vector3Var"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteVector3Var), createConstant, typeof(BehaviourMachine.ConcreteVector3Var)); menu.AddItem(new GUIContent("Constant/RectVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteRectVar), createConstant, typeof(BehaviourMachine.ConcreteRectVar)); menu.AddItem(new GUIContent("Constant/ColorVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteColorVar), createConstant, typeof(BehaviourMachine.ConcreteColorVar)); menu.AddItem(new GUIContent("Constant/QuaternionVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteQuaternionVar), createConstant, typeof(BehaviourMachine.ConcreteQuaternionVar)); menu.AddItem(new GUIContent("Constant/GameObjectVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteGameObjectVar), createConstant, typeof(BehaviourMachine.ConcreteGameObjectVar)); menu.AddItem(new GUIContent("Constant/MaterialVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteMaterialVar), createConstant, typeof(BehaviourMachine.ConcreteMaterialVar)); menu.AddItem(new GUIContent("Constant/TextureVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteTextureVar), createConstant, typeof(BehaviourMachine.ConcreteTextureVar)); menu.AddItem(new GUIContent("Constant/ObjectVar"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteObjectVar), createConstant, typeof(BehaviourMachine.ConcreteObjectVar)); } else if (variable != null) { // Get the base type System.Type baseType = BehaviourMachine.TypeUtility.GetBaseType(variable.GetType()); if (baseType == typeof(Variable)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.Variable), createConstant, typeof(BehaviourMachine.Variable)); } else if (baseType == typeof(FloatVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteFloatVar), createConstant, typeof(BehaviourMachine.ConcreteFloatVar)); } else if (baseType == typeof(IntVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteIntVar), createConstant, typeof(BehaviourMachine.ConcreteIntVar)); } else if (baseType == typeof(BoolVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteBoolVar), createConstant, typeof(BehaviourMachine.ConcreteBoolVar)); } else if (baseType == typeof(StringVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteStringVar), createConstant, typeof(BehaviourMachine.ConcreteStringVar)); } else if (baseType == typeof(Vector3Var)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteVector3Var), createConstant, typeof(BehaviourMachine.ConcreteVector3Var)); } else if (baseType == typeof(RectVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteRectVar), createConstant, typeof(BehaviourMachine.ConcreteRectVar)); } else if (baseType == typeof(ColorVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteColorVar), createConstant, typeof(BehaviourMachine.ConcreteColorVar)); } else if (baseType == typeof(QuaternionVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteQuaternionVar), createConstant, typeof(BehaviourMachine.ConcreteQuaternionVar)); } else if (baseType == typeof(GameObjectVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteGameObjectVar), createConstant, typeof(BehaviourMachine.ConcreteGameObjectVar)); } else if (baseType == typeof(MaterialVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteMaterialVar), createConstant, typeof(BehaviourMachine.ConcreteMaterialVar)); } else if (baseType == typeof(TextureVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteTextureVar), createConstant, typeof(BehaviourMachine.ConcreteTextureVar)); } else if (baseType == typeof(ObjectVar)) { menu.AddItem(new GUIContent("Constant"), isConstant && variableNotNull && variable.GetType() == typeof(BehaviourMachine.ConcreteObjectVar), createConstant, typeof(BehaviourMachine.ConcreteObjectVar)); } } } } else { menu.AddDisabledItem(new GUIContent("Constant")); } // Custom variables if (property.type != null) { System.Type[] customVars = CustomVariableUtility.GetCustomVariables(variableInfo.fixedType && variable != null ? BehaviourMachine.TypeUtility.GetBaseType(variable.GetType()) : property.type); // if (customVars.Length > 0) { // menu.AddSeparator(string.Empty); // } for (int i = 0; i < customVars.Length; i++) { // Get the type of the custom variable System.Type customVarType = customVars[i]; // Get a unique name string uniqueName = StringHelper.GetUniqueNameInList(names, "Custom/" + customVarType.Name); names.Add(uniqueName); // Add to the menu menu.AddItem(new GUIContent(uniqueName), isConstant && variable != null && variable.GetType() == customVarType, delegate { try { var newVariable = Activator.CreateInstance(customVarType, new object[] { node.self }) as Variable; if (newVariable != null) { newVariable.SetAsConstant(); property.value = newVariable; } } catch (Exception e) { Print.LogError(e.ToString()); } }); } } // Boolean used to know if the variables separator was already added to the menu. bool separatorAdded = false; // Blackboard variables var variables = node.self.GetComponent <InternalBlackboard>().GetVariables(variable != null && variableInfo.fixedType ? BehaviourMachine.TypeUtility.GetBaseType(variable.GetType()) : property.type); // Add separator? if (variables.Count > 0) { menu.AddSeparator(string.Empty); separatorAdded = true; } // Blackboard variables for (int i = 0; i < variables.Count; i++) { var v = variables[i]; var name = StringHelper.GetUniqueNameInList(names, v.name); names.Add(name); menu.AddItem(new GUIContent(name), variable == v, delegate { property.value = v; }); } // Global variables if (InternalGlobalBlackboard.Instance != null) { var globalVariables = InternalGlobalBlackboard.Instance.GetVariables(property.type); // Add separator? if (!separatorAdded && globalVariables.Count > 0) { menu.AddSeparator(string.Empty); separatorAdded = true; } for (int i = 0; i < globalVariables.Count; i++) { var v = globalVariables[i]; var name = StringHelper.GetUniqueNameInList(names, "Global/" + v.name); names.Add(name); menu.AddItem(new GUIContent(name), variable == v, delegate { property.value = v; }); } } // Show menu menu.DropDown(rect); // Set GUI as not changed GUI.changed = false; } // Draw constant properties if (isConstant) { // Get children var children = property.children; // The variable is an ObjectVar? var objectVar = variable as ObjectVar; System.Type objType = objectVar != null ? objectVar.ObjectType : null; // Draw properties if (children.Length > 0) { EditorGUI.indentLevel++; if (property.isConcreteVariable) { for (int i = 0; i < children.Length; i++) { SerializedNodeProperty childProperty = children[i]; if (!childProperty.hideInInspector) { if (childProperty.propertyType == NodePropertyType.Vector3 || childProperty.propertyType == NodePropertyType.Quaternion || childProperty.propertyType == NodePropertyType.Vector2) { #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 GUILayout.Space(-20f); EditorGUI.indentLevel--; #endif DrawNodeProperty(GUIContent.none, childProperty, node, objType); #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 EditorGUI.indentLevel++; #endif } else if (childProperty.propertyType == NodePropertyType.Rect) { #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 GUILayout.Space(-20f); EditorGUI.indentLevel--; #endif DrawNodeProperty(GUIContent.none, childProperty, node, objType); #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 GUILayout.Space(20f); EditorGUI.indentLevel++; #endif } else { DrawNodeProperty(new GUIContent(childProperty.label, childProperty.tooltip), childProperty, node, objType); } } } } else { for (int i = 0; i < children.Length; i++) { SerializedNodeProperty childProperty = children[i]; if (!childProperty.hideInInspector) { DrawNodeProperty(new GUIContent(childProperty.label, childProperty.tooltip), childProperty, node, objType); } } } EditorGUI.indentLevel--; } } }