/// <summary> /// Moves to the next property. /// <param name="enterChildren">Should iterate through the current property children?</param> /// <returns>The current property is valid?</returns> /// </summary> public bool Next(bool enterChildren) { // The current property has children? if (enterChildren && this.m_Current != null && this.m_Current.hasChildren) { m_ParentPropertiesIndex.Push(m_CurrentIndex); m_ParentProperties.Push(m_Properties); m_Properties = this.m_Current.children; m_CurrentIndex = 0; m_Current = m_Properties[0]; return(true); } // Get next property else if (++m_CurrentIndex < m_Properties.Length) { m_Current = m_Properties[m_CurrentIndex]; return(true); } // Restore last property set else if (m_ParentProperties.Count > 0) { m_Properties = m_ParentProperties.Pop(); m_CurrentIndex = m_ParentPropertiesIndex.Pop(); return(this.Next(enterChildren)); } return(false); }
// // Methods // public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { UnityVariablePropertyAttribute att = (UnityVariablePropertyAttribute)attribute; BlackboardCustom blackboard = node.blackboard as BlackboardCustom; List<UnityVariable> blackboardLocalList = blackboard.GetVariableBy (att.variableType); List<GUIContent> displayOptionsList = blackboardLocalList.Select ((item) => new GUIContent ("Local/" + item.name)).ToList (); EditorGUILayout.BeginHorizontal (); // property.serializedNode.ApplyModifiedProperties (); EditorGUI.BeginChangeCheck (); //EditorGUILayout.LabelField (att.name,new GUILayoutOption[]{GUILayout.MaxWidth(80)}); property.value = EditorGUILayoutEx.UnityVariablePopup (new GUIContent(att.name), property.value as UnityVariable, att.variableType, displayOptionsList, blackboardLocalList); if (EditorGUI.EndChangeCheck ()) { property.serializedNode.ApplyModifiedProperties (); } EditorGUILayout.EndHorizontal (); }
/// <summary> /// Draw the UnityEngine.Object types pop-up. /// </summary> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // String if (property.propertyType == NodePropertyType.String) { var stringValue = property.value as string ?? string.Empty; var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup); var id = GUIUtility.GetControlID(FocusType.Passive); var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent); var objectType = UnityObjectTypeAttribute.GetObjectType(stringValue); if (GUI.Button(popupRect, objectType != null ? objectType.ToString() : "None", EditorStyles.popup)) { var menu = new GenericMenu(); // Add None menu.AddItem(new GUIContent("None"), string.IsNullOrEmpty(stringValue), delegate { property.value = string.Empty; }); // Add all types that inherit from UnityEngine.Object var types = TypeUtility.GetDerivedTypes(typeof(UnityEngine.Object)); for (int i = 0; i < types.Length; i++) { var typeAsString = types[i].ToString(); menu.AddItem(new GUIContent(typeAsString.Replace('.', '/')), stringValue == typeAsString, delegate { property.value = typeAsString; }); } menu.ShowAsContext(); } } // Not String else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use UnityObjectType with string.")); } }
/// <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="arrayData">The serialize property of the target array.</param> /// <param name="array">The target array.</param> /// <param name="elementType">The array element type.</param> /// </summary> public SerializedArraySize(object target, SerializedNode serializedNode, string path, SerializedNodeProperty arrayData, Array array, Type elementType) : base(target, serializedNode, path, typeof(int), NodePropertyType.ArraySize) { m_ArrayData = arrayData; m_Array = array; m_ElementType = elementType; this.label = "Size"; }
/// <summary> /// Called by the serialized properties when their data change. /// <param name="property">The property value that has changed.</param> /// </summary> public void PropertyDataChanged(SerializedNodeProperty property) { if (property.serializedNode == this && !m_PropertiesChanged.Contains(property)) { m_PropertiesChanged.Add(property); } }
public override void OnGUI(SerializedNodeProperty property, BehaviourMachine.ActionNode node, GUIContent guiContent) { // Now draw the property as a Slider or an IntSlider based on whether it’s a float or integer. if ( property.type != typeof(MinMaxRangeSO) ) Debug.LogWarning( "Use only with MinMaxRange type" ); else { var range = attribute as MinMaxRangeSAttribute; var so=(MinMaxRangeSO)property.value; //set or reset to default full range if(so.rangeStart==so.rangeEnd){ so.rangeStart=range.minLimit; so.rangeEnd=range.maxLimit; } var newMin =so.rangeStart; var newMax = so.rangeEnd; Rect position= GUILayoutUtility.GetRect(Screen.width-32f,32f); var xDivision = position.width * 0.33f; var yDivision = position.height * 0.5f; EditorGUI.LabelField( new Rect( position.x, position.y, xDivision, yDivision ) , guiContent ); EditorGUI.LabelField( new Rect( position.x, position.y + yDivision, position.width, yDivision ) , range.minLimit.ToString( "0.##" ) ); EditorGUI.LabelField( new Rect( position.x + position.width -28f, position.y + yDivision, position.width, yDivision ) , range.maxLimit.ToString( "0.##" ) ); EditorGUI.MinMaxSlider( new Rect( position.x + 24f, position.y + yDivision, position.width -48f, yDivision ) , ref newMin, ref newMax, range.minLimit, range.maxLimit ); EditorGUI.LabelField( new Rect( position.x + xDivision, position.y, xDivision, yDivision ) , "From: " ); newMin = Mathf.Clamp( EditorGUI.FloatField( new Rect( position.x + xDivision + 30, position.y, xDivision -30, yDivision ) , newMin ) , range.minLimit, newMax ); EditorGUI.LabelField( new Rect( position.x + xDivision * 2f, position.y, xDivision, yDivision ) , "To: " ); newMax = Mathf.Clamp( EditorGUI.FloatField( new Rect( position.x + xDivision * 2f + 24, position.y, xDivision -24, yDivision ) , newMax ) , newMin, range.maxLimit ); so.rangeStart = newMin; so.rangeEnd = newMax; property.ValueChanged(); property.ApplyModifiedValue(); property.serializedNode.ApplyModifiedProperties(); } }
/// <summary> /// Draw the UnityEngine.Object using the objectType field. /// </summary> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // Object if (property.propertyType == NodePropertyType.UnityObject) { // Get the type path var attr = this.attribute as ObjectValueAttribute; string path = property.path; int lastDotIndex = path.LastIndexOf('.'); if (lastDotIndex > -1) { path = path.Remove(lastDotIndex + 1, path.Length - lastDotIndex - 1); } else { path = string.Empty; } // Get the property iterator NodePropertyIterator iterator = property.serializedNode.GetIterator(); // The type of the object string objectTypeAsString = string.Empty; // Get the object type as string if (iterator.Find(path + attr.typePropertyPath)) { SerializedNodeProperty typeProperty = iterator.current; objectTypeAsString = typeProperty.value as string ?? string.Empty; } // Get the object type System.Type objectType = !string.IsNullOrEmpty(objectTypeAsString) ? BehaviourMachine.TypeUtility.GetType(objectTypeAsString) ?? typeof(UnityEngine.Object) : typeof(UnityEngine.Object); // Used to detect if the gui control was changed EditorGUI.BeginChangeCheck(); // Draw the object gui control UnityEngine.Object newValue = EditorGUILayout.ObjectField(guiContent, property.value as UnityEngine.Object, objectType, !AssetDatabase.Contains(node.self)); // Value changed? if (EditorGUI.EndChangeCheck()) { property.value = newValue; } } // Not Object else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use ObjectValue with UnityEngine.Object.")); } }
/// <summary> /// Draw the slider. /// </summary> public override void OnGUI (SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // Integer if (property.propertyType == NodePropertyType.Integer) { var range = base.attribute as RangeAttribute; property.value = EditorGUILayout.IntSlider (guiContent, (int)property.value, (int)range.min, (int)range.max); } // Float else if (property.propertyType == NodePropertyType.Float) { var range = base.attribute as RangeAttribute; property.value = EditorGUILayout.Slider (guiContent, (float)property.value, range.min, range.max); } else EditorGUILayout.LabelField(guiContent, new GUIContent("Use range with float or int.")); }
/// <summary> /// Draw the state pop-up. /// </summary> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // InternalStateBehaviour if (property.propertyType == NodePropertyType.UnityObject && property.type == typeof(InternalStateBehaviour)) { var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup); var id = GUIUtility.GetControlID(FocusType.Passive); var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent); var state = property.value as InternalStateBehaviour; // Set the pop-up color var oldGUIColor = GUI.color; if (state == null) { GUI.color = Color.red; } if (GUI.Button(popupRect, state != null ? state.stateName : "Null", EditorStyles.popup)) { // Get states var states = node.tree.states; // Create the pop-up menu var menu = new GenericMenu(); // Add null menu.AddItem(new GUIContent("Null"), state == null, delegate() { property.value = (InternalStateBehaviour)null; }); // Add states for (int i = 0; i < states.Count; i++) { InternalStateBehaviour currentState = states[i]; //setField = field != null ? new SetField(this.target, target, states[i], field, m_Tree) : new SetField(this.target, arrayField, index, states[i], m_Tree); menu.AddItem(new GUIContent(states[i].stateName), state == states[i], delegate() { property.value = currentState; }); } // Show menu menu.ShowAsContext(); } // Restore GUI.color GUI.color = oldGUIColor; } else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use TreeState with InternalStateBehaviour.")); } }
// // Methods // public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { Enum @enum; if (Enum.IsDefined (this.attribute.GetEnumType (), property.value)) { @enum = (Enum)Enum.ToObject (this.attribute.GetEnumType (), property.value); } else { @enum = this.attribute.GetEnumValue (); } @enum=EditorGUILayout.EnumPopup (@enum); property.value= ((int)Convert.ChangeType (@enum, @enum.GetTypeCode ())); property.ApplyModifiedValue (); }
/// <summary> /// Draw the slider. /// </summary> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // Integer if (property.propertyType == NodePropertyType.Integer) { var range = base.attribute as RangeAttribute; property.value = EditorGUILayout.IntSlider(guiContent, (int)property.value, (int)range.min, (int)range.max); } // Float else if (property.propertyType == NodePropertyType.Float) { var range = base.attribute as RangeAttribute; property.value = EditorGUILayout.Slider(guiContent, (float)property.value, range.min, range.max); } else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use range with float or int.")); } }
/// <summary> /// Draw the property pop-up. /// </summary> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // String if (property.propertyType == NodePropertyType.String) { var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup); var id = GUIUtility.GetControlID(FocusType.Passive); var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent); var popupName = property.value as string ?? string.Empty; var propertyOrField = node as PropertyOrField; var oldGUIColor = GUI.color; if (propertyOrField.propertyType == null) { GUI.color = Color.red; } if (GUI.Button(popupRect, string.IsNullOrEmpty(popupName) ? "None" : popupName, EditorStyles.popup)) { var isSetProperty = propertyOrField is SetProperty; var members = FieldUtility.GetPublicMembers(propertyOrField.targetObject.ObjectType, null, false, isSetProperty, !isSetProperty); var menu = new GenericMenu(); // Add none menu.AddItem(new GUIContent("None"), string.IsNullOrEmpty(popupName), delegate() { property.value = string.Empty; }); // Add members for (int i = 0; i < members.Length; i++) { var memberName = members[i].Name; menu.AddItem(new GUIContent(memberName), popupName == memberName, delegate() { property.value = memberName; }); } menu.ShowAsContext(); } GUI.color = oldGUIColor; } // Not String else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use UnityObjectProperty with string.")); } }
/// <summary> /// Draw the UnityEngine.Object using the objectType field. /// </summary> public override void OnGUI (SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // Object if (property.propertyType == NodePropertyType.UnityObject) { // Get the type path var attr = this.attribute as ObjectValueAttribute; string path = property.path; int lastDotIndex = path.LastIndexOf('.'); if (lastDotIndex > -1) path = path.Remove(lastDotIndex + 1, path.Length - lastDotIndex - 1); else path = string.Empty; // Get the property iterator NodePropertyIterator iterator = property.serializedNode.GetIterator(); // The type of the object string objectTypeAsString = string.Empty; // Get the object type as string if (iterator.Find(path + attr.typePropertyPath)) { SerializedNodeProperty typeProperty = iterator.current; objectTypeAsString = typeProperty.value as string ?? string.Empty; } // Get the object type System.Type objectType = !string.IsNullOrEmpty(objectTypeAsString) ? BehaviourMachine.TypeUtility.GetType(objectTypeAsString) ?? typeof(UnityEngine.Object) : typeof(UnityEngine.Object); // Used to detect if the gui control was changed EditorGUI.BeginChangeCheck(); // Draw the object gui control UnityEngine.Object newValue = EditorGUILayout.ObjectField(guiContent, property.value as UnityEngine.Object, objectType, !AssetDatabase.Contains(node.self)); // Value changed? if (EditorGUI.EndChangeCheck()) property.value = newValue; } // Not Object else EditorGUILayout.LabelField(guiContent, new GUIContent("Use ObjectValue with UnityEngine.Object.")); }
public void DrawDefaultInspector() { // Get an iterator var iterator = m_SerializedNode.GetIterator(); // Cache the indent level int indentLevel = EditorGUI.indentLevel; while (iterator.Next(iterator.current == null || (iterator.current.propertyType != NodePropertyType.Variable && !iterator.current.hideInInspector))) { SerializedNodeProperty current = iterator.current; if (!current.hideInInspector) { EditorGUI.indentLevel = indentLevel + iterator.depth; GUILayoutHelper.DrawNodeProperty(new GUIContent(current.label, current.tooltip), current, m_Target); } } // Restore the indent level EditorGUI.indentLevel = indentLevel; }
/// <summary> /// Draw the state pop-up. /// </summary> public override void OnGUI (SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // InternalStateBehaviour if (property.propertyType == NodePropertyType.UnityObject && property.type == typeof(InternalStateBehaviour)) { var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup); var id = GUIUtility.GetControlID(FocusType.Passive); var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent); var state = property.value as InternalStateBehaviour; // Set the pop-up color var oldGUIColor = GUI.color; if (state == null) GUI.color = Color.red; if (GUI.Button(popupRect, state != null ? state.stateName : "Null", EditorStyles.popup)) { // Get states var states = node.tree.states; // Create the pop-up menu var menu = new GenericMenu(); // Add null menu.AddItem(new GUIContent("Null"), state == null, delegate () {property.value = (InternalStateBehaviour)null;}); // Add states for (int i = 0; i < states.Count; i++) { InternalStateBehaviour currentState = states[i]; //setField = field != null ? new SetField(this.target, target, states[i], field, m_Tree) : new SetField(this.target, arrayField, index, states[i], m_Tree); menu.AddItem(new GUIContent(states[i].stateName), state == states[i], delegate () {property.value = currentState;}); } // Show menu menu.ShowAsContext(); } // Restore GUI.color GUI.color = oldGUIColor; } else EditorGUILayout.LabelField(guiContent, new GUIContent("Use TreeState with InternalStateBehaviour.")); }
/// <summary> /// Moves to the next property. /// <param name="enterChildren">Should iterate through the current property children?</param> /// <returns>The current property is valid?</returns> /// </summary> public bool Next (bool enterChildren) { // The current property has children? if (enterChildren && this.m_Current != null && this.m_Current.hasChildren) { m_ParentPropertiesIndex.Push(m_CurrentIndex); m_ParentProperties.Push(m_Properties); m_Properties = this.m_Current.children; m_CurrentIndex = 0; m_Current = m_Properties[0]; return true; } // Get next property else if (++m_CurrentIndex < m_Properties.Length) { m_Current = m_Properties[m_CurrentIndex]; return true; } // Restore last property set else if (m_ParentProperties.Count > 0) { m_Properties = m_ParentProperties.Pop(); m_CurrentIndex = m_ParentPropertiesIndex.Pop(); return this.Next(enterChildren); } return false; }
// // Methods // public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { attribute.serializedObject = node; GUILayout.BeginHorizontal (); if (attribute.Min < attribute.Max) { if (attribute.HasEnableToggle) attribute.Enabled = GUILayout.Toggle (attribute.Enabled, property.label); if (attribute.Enabled) { GUILayout.Label (attribute.Min.ToString ()); _valueCurrent = GUILayout.HorizontalSlider (_valueCurrent, attribute.Min, attribute.Max); property.value = _valueCurrent; GUILayout.Label (attribute.Max.ToString ()); property.ApplyModifiedValue (); } } GUILayout.EndHorizontal (); }
/// <summary> /// Called by the serialized properties when their data change. /// <param name="property">The property value that has changed.</param> /// </summary> public void PropertyDataChanged (SerializedNodeProperty property) { if (property.serializedNode == this && !m_PropertiesChanged.Contains(property)) m_PropertiesChanged.Add(property); }
/// <summary> /// Show the specified space, clip, node and position. /// </summary> /// <param name="space">Space.</param> /// <param name="clip">Clip.</param> /// <param name="node">Node.</param> /// <param name="position">Position.</param> public static void Show(GameObject space,AnimationClip clip, SerializedNode node, Rect? position) { MecanimNodeEditorWindow.__spaceGameObject = space;//in this case is character MecanimNodeEditorWindow.__spaceGameObjectAnimationClip = clip; MecanimNodeEditorWindow.__serializedNode = node; /////// ACCESS SERIALIZED DATA ///////// NodePropertyIterator iterator = node.GetIterator (); __isPlaying = false; __isRecording = false; __variableSelected = null; __timeNormalized = 0f; __timeNormalizedUpdate = false; __timeCurrent = 0f; AnimationMode.StopAnimationMode (); Undo.postprocessModifications -= PostprocessAnimationRecordingModifications; SceneView.onSceneGUIDelegate += OnSceneGUI; if (iterator.Find ("clipBindings")) clipBindingsSerialized = iterator.current; if (__mecanimNodeClipBinding == null) __mecanimNodeClipBinding = ScriptableObject.CreateInstance<EditorClipBinding> (); __mecanimNodeClipBinding.gameObject = __spaceGameObject; __mecanimNodeClipBinding.clip = __spaceGameObjectAnimationClip; /////// INIT SERIALIZED NODE PROPERTIES - CURVES, COLORS, VARIABLES ////// if (iterator.Find ("curves")) curvesSerialized = iterator.current; else Debug.LogError ("MecananimNode should have public field 'curves'"); if (iterator.Find ("curvesColors")) curvesColorsSerialized = iterator.current; else Debug.LogError ("MecananimNode should have public field 'curvesColors'"); if (iterator.Find ("variablesBindedToCurves")) variablesBindedToCurvesSerialized = iterator.current; else Debug.LogError ("MecananimNode should have public field 'variablesBindedToCurves'"); curves = (AnimationCurve[])curvesSerialized.value; curveColors = (Color[])curvesColorsSerialized.value; variablesBindedToCurves = (UnityVariable[])variablesBindedToCurvesSerialized.value; AnimationModeUtility.ResetBindingsTransformPropertyModification (clipBindingsSerialized.value as EditorClipBinding[]); AnimationModeUtility.ResetBindingTransformPropertyModification (__mecanimNodeClipBinding); keyframeTimeValues = new float[0]; eventTimeValuesPrev = new float[0]; keyframeTimeValuesSelected = new bool[0]; keyframesDisplayNames = new string[0]; ///////////// create Reordable list of gameObject-animationClip ////////////////// __gameObjectClipList = new ReorderableList (clipBindingsSerialized.value as IList, typeof(EditorClipBinding), true, true, true, true); __gameObjectClipList.drawElementCallback = onDrawElement; __gameObjectClipList.drawHeaderCallback = onDrawHeaderElement; __gameObjectClipList.onRemoveCallback = onRemoveCallback; __gameObjectClipList.onAddCallback = onAddCallback; __gameObjectClipList.onSelectCallback = onSelectCallback; //__gameObjectClipList.elementHeight = 32f; if (MecanimNodeEditorWindow.__window != null)//restore last position = __window.position; MecanimNodeEditorWindow.__window = (MecanimNodeEditorWindow)EditorWindow.GetWindow (typeof(MecanimNodeEditorWindow)); if (position.HasValue) MecanimNodeEditorWindow.__window.position = position.Value; MecanimNodeEditorWindow.__window.Show (); }
/// <summary> /// Draw the TextArea. /// </summary> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // The text to display string text; // string if (property.propertyType == NodePropertyType.String) { // Get the text text = property.value as string ?? string.Empty; } // StringVar else if (property.propertyType == NodePropertyType.Variable && property.type == typeof(StringVar)) { // Get the text var stringVar = property.value as StringVar; if (stringVar != null) { text = stringVar.Value as string ?? string.Empty; } else { text = string.Empty; } } // Not supported else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use TextAreaAttribute with string or StringVar.")); return; } // Create style? if (s_Styles == null) { s_Styles = new NodeTextAreaDrawer.Styles(); } // Get the text area var textAreaAttr = (NodeTextAreaAttribute)attribute; // Store the current content color Color contentColor = GUI.contentColor; // The text is empty? if (string.IsNullOrEmpty(text)) { text = textAreaAttr.hint; Color textColor = EditorStyles.label.normal.textColor; textColor.a = .5f; GUI.contentColor = textColor; } // Draw the text area. EditorGUI.BeginChangeCheck(); #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 string value = EditorGUILayout.TextArea(text, s_Styles.textArea, GUILayout.Height(16f * textAreaAttr.lines)); #else string value = EditorGUILayout.TextArea(text, s_Styles.textArea, GUILayout.Height(EditorGUIUtility.singleLineHeight * textAreaAttr.lines)); #endif // Check for changes if (EditorGUI.EndChangeCheck()) { if (property.propertyType == NodePropertyType.String) { property.value = value; } else { // Get the text var stringVar = property.value as StringVar; if (stringVar != null) { stringVar.Value = value; property.ValueChanged(); } } } // Restore content color GUI.contentColor = contentColor; }
/// <summary> /// Override this method to make your own GUI for the property. /// </summary> public abstract void OnGUI (SerializedNodeProperty property, ActionNode node, GUIContent guiContent);
/// <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="arrayData">The serialize property of the target array.</param> /// <param name="array">The target array.</param> /// <param name="elementType">The array element type.</param> /// </summary> public SerializedArraySize (object target, SerializedNode serializedNode, string path, SerializedNodeProperty arrayData, Array array, Type elementType) : base (target, serializedNode, path, typeof(int), NodePropertyType.ArraySize) { m_ArrayData = arrayData; m_Array = array; m_ElementType = elementType; this.label = "Size"; }
/// <summary> /// Draws a node property in the GUI. /// <param name="guiContent">The content of the property.</param> /// <param name="property">The property do be drawn.</param> /// <param name="node">The node that owns the property.</param> /// <param name="objectType">An optionaly type to be used to with UnityEngine.Object properties.</param> /// <param name="useCustomDrawer">If false the custom node drawer will be ignored if it exists.</param> /// </summary> public static void DrawNodeProperty(GUIContent guiContent, SerializedNodeProperty property, ActionNode node, Type objectType = null, bool useCustomDrawer = true) { if (s_Styles == null) { s_Styles = new GUILayoutHelper.Styles(); } // Get the current value object value = property.value; // Create the newValue object newValue = value; // Variable? if (property.propertyType == NodePropertyType.Variable) { GUILayoutHelper.VariableField(guiContent, property, node); } // Use custom property drawer? else if (useCustomDrawer && property.customDrawer != null) { property.customDrawer.OnGUI(property, node, guiContent); return; } else { EditorGUI.BeginChangeCheck(); switch (property.propertyType) { // Integer case NodePropertyType.Integer: newValue = EditorGUILayout.IntField(guiContent, value != null ? (int)value : 0); break; // Float case NodePropertyType.Float: newValue = EditorGUILayout.FloatField(guiContent, (float)value); break; // Boolean case NodePropertyType.Boolean: newValue = EditorGUILayout.Toggle(guiContent, (bool)value); break; // String case NodePropertyType.String: newValue = EditorGUILayout.TextField(guiContent, (string)value); break; // Color case NodePropertyType.Color: newValue = EditorGUILayout.ColorField(guiContent, (Color)value); break; // Vector2 case NodePropertyType.Vector2: #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 newValue = EditorGUILayout.Vector2Field(guiContent.text, (Vector2)value); #else newValue = EditorGUILayout.Vector2Field(guiContent, (Vector2)value); #endif break; // Vector3 case NodePropertyType.Vector3: #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 newValue = EditorGUILayout.Vector3Field(guiContent.text, (Vector3)value); #else newValue = EditorGUILayout.Vector3Field(guiContent, (Vector3)value); #endif break; // Quaternion case NodePropertyType.Quaternion: #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 newValue = Quaternion.Euler(EditorGUILayout.Vector3Field(guiContent.text, ((Quaternion)value).eulerAngles)); #else newValue = Quaternion.Euler(EditorGUILayout.Vector3Field(guiContent, ((Quaternion)value).eulerAngles)); #endif break; // Vector4 case NodePropertyType.Vector4: newValue = EditorGUILayout.Vector4Field(guiContent.text, (Vector4)value); break; // Rect case NodePropertyType.Rect: newValue = EditorGUILayout.RectField(guiContent, (Rect)value); break; // Enum case NodePropertyType.Enum: newValue = EditorGUILayout.EnumPopup(guiContent, (System.Enum)value); break; // AnimationCurve case NodePropertyType.AnimationCurve: newValue = EditorGUILayout.CurveField(guiContent, (AnimationCurve)value); break; // UnityObject case NodePropertyType.UnityObject: newValue = EditorGUILayout.ObjectField(guiContent, value as UnityEngine.Object, objectType != null ? objectType : property.type, !AssetDatabase.Contains(node.self)); break; // Array case NodePropertyType.Array: EditorGUILayout.LabelField(guiContent); GUI.changed = false; break; // ArraySize case NodePropertyType.ArraySize: goto case NodePropertyType.Integer; // LayerMask case NodePropertyType.LayerMask: newValue = GUILayoutHelper.LayerMaskField(guiContent, (LayerMask)value); break; // Not Supported default: Color oldGuiColor = GUI.color; GUI.color = Color.red; EditorGUILayout.LabelField(guiContent.text, "Not supported."); GUI.color = oldGuiColor; break; } // Value changed? if (EditorGUI.EndChangeCheck()) { property.value = newValue; Event.current.Use(); } } }
/// <summary> /// Returns the first state of the iterator. /// </summary> public void Reset() { m_CurrentIndex = -1; m_Current = null; }
/// <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--; } } }
/// <summary> /// Draws a node property in the GUI. /// <param name="guiContent">The content of the property.</param> /// <param name="property">The property do be drawn.</param> /// <param name="node">The node that owns the property.</param> /// <param name="objectType">An optionaly type to be used to with UnityEngine.Object properties.</param> /// <param name="useCustomDrawer">If false the custom node drawer will be ignored if it exists.</param> /// </summary> public static void DrawNodeProperty (GUIContent guiContent, SerializedNodeProperty property, ActionNode node, Type objectType = null, bool useCustomDrawer = true) { if (s_Styles == null) s_Styles = new GUILayoutHelper.Styles(); // Get the current value object value = property.value; // Create the newValue object newValue = value; // Variable? if (property.propertyType == NodePropertyType.Variable) { GUILayoutHelper.VariableField(guiContent, property, node); } // Use custom property drawer? else if (useCustomDrawer && property.customDrawer != null) { property.customDrawer.OnGUI(property, node, guiContent); return; } else { EditorGUI.BeginChangeCheck(); switch (property.propertyType) { // Integer case NodePropertyType.Integer: newValue = EditorGUILayout.IntField(guiContent, value != null ? (int) value : 0); break; // Float case NodePropertyType.Float: newValue = EditorGUILayout.FloatField(guiContent, (float) value); break; // Boolean case NodePropertyType.Boolean: newValue = EditorGUILayout.Toggle(guiContent, (bool) value); break; // String case NodePropertyType.String: newValue = EditorGUILayout.TextField(guiContent, (string) value); break; // Color case NodePropertyType.Color: newValue = EditorGUILayout.ColorField(guiContent, (Color) value); break; // Vector2 case NodePropertyType.Vector2: #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 newValue = EditorGUILayout.Vector2Field(guiContent.text, (Vector2) value); #else newValue = EditorGUILayout.Vector2Field(guiContent, (Vector2) value); #endif break; // Vector3 case NodePropertyType.Vector3: #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 newValue = EditorGUILayout.Vector3Field(guiContent.text, (Vector3) value); #else newValue = EditorGUILayout.Vector3Field(guiContent, (Vector3) value); #endif break; // Quaternion case NodePropertyType.Quaternion: #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 newValue = Quaternion.Euler(EditorGUILayout.Vector3Field(guiContent.text, ((Quaternion)value).eulerAngles)); #else newValue = Quaternion.Euler(EditorGUILayout.Vector3Field(guiContent, ((Quaternion)value).eulerAngles)); #endif break; // Vector4 case NodePropertyType.Vector4: newValue = EditorGUILayout.Vector4Field(guiContent.text, (Vector4) value); break; // Rect case NodePropertyType.Rect: newValue = EditorGUILayout.RectField(guiContent, (Rect) value); break; // Enum case NodePropertyType.Enum: newValue = EditorGUILayout.EnumPopup(guiContent, (System.Enum) value); break; // AnimationCurve case NodePropertyType.AnimationCurve: newValue = EditorGUILayout.CurveField(guiContent, (AnimationCurve) value); break; // UnityObject case NodePropertyType.UnityObject: newValue = EditorGUILayout.ObjectField(guiContent, value as UnityEngine.Object, objectType != null ? objectType : property.type, !AssetDatabase.Contains(node.self)); break; // Array case NodePropertyType.Array: EditorGUILayout.LabelField(guiContent); GUI.changed = false; break; // ArraySize case NodePropertyType.ArraySize: goto case NodePropertyType.Integer; // LayerMask case NodePropertyType.LayerMask: newValue = GUILayoutHelper.LayerMaskField(guiContent, (LayerMask) value); break; // Not Supported default: Color oldGuiColor = GUI.color; GUI.color = Color.red; EditorGUILayout.LabelField(guiContent.text, "Not supported."); GUI.color = oldGuiColor; break; } // Value changed? if (EditorGUI.EndChangeCheck()) { property.value = newValue; Event.current.Use(); } } }
/// <summary> /// Constructor. /// <param name="members">The serialized properties to iterate through.</param> /// </summary> public NodePropertyIterator (SerializedNodeProperty[] members) { m_Properties = members; }
/// <summary> /// Returns the first state of the iterator. /// </summary> public void Reset () { m_CurrentIndex = -1; m_Current = null; }
public override void OnGUI(SerializedNodeProperty property, BehaviourMachine.ActionNode node, GUIContent guiContent) { Rect position= GUILayoutUtility.GetRect(Screen.width-32f,32f); Rect typePos = new Rect (position.x, position.y, 80, position.height); position.xMin = typePos.xMax; Rect varPos = new Rect (position.x, position.y, position.width, position.height); Type type; GUIContent[] displayOptionsTypes; Type[] types; UniUnityVariablePropertyAttribute attributeUni = attribute as UniUnityVariablePropertyAttribute; if (property.value == null) type = EditorGUILayoutEx.unityTypes [0]; else type = ((UnityVariable)property.value).ValueType; //blackboard vars LOCAL BlackboardCustom blackboard = node.blackboard as BlackboardCustom; List<UnityVariable> blackboardVariablesLocalList = blackboard.GetVariableBy (type); List<GUIContent> displayOptionsVariablesLocal= blackboardVariablesLocalList.Select ((item) => new GUIContent ("Local/" + item.name)).ToList(); //blackboard vars GLOBAL if (attributeUni.typesCustom != null) { GUIContent[] displayOptionsCustom=attributeUni.typesCustom.Select((itm)=>new GUIContent(itm.Name)).ToArray(); if(attributeUni.only){ types=attributeUni.typesCustom; displayOptionsTypes=displayOptionsCustom; }else{ types=attributeUni.typesCustom.Concat<Type>(EditorGUILayoutEx.unityTypes).ToArray(); displayOptionsTypes = displayOptionsCustom.Concat<GUIContent>(EditorGUILayoutEx.unityTypesDisplayOptions).ToArray(); } }else{ displayOptionsTypes=EditorGUILayoutEx.unityTypesDisplayOptions; types=EditorGUILayoutEx.unityTypes; } //String name = attributeUni.name; //create types selection popup typeSelected = EditorGUILayoutEx.CustomObjectPopup<Type> (null, type,displayOptionsTypes , types,null,null,null,null,typePos); //if change of type create new variable if (typeSelected != type && !typeSelected.IsSubclassOf (type) /*&& type!=typeof(UnityEngine.Object)*/) { property.value = UnityVariable.CreateInstanceOf(typeSelected); } property.value=EditorGUILayoutEx.UnityVariablePopup(null,property.value as UnityVariable,typeSelected,displayOptionsVariablesLocal,blackboardVariablesLocalList,varPos); property.serializedNode.ApplyModifiedProperties(); }
/// <summary> /// Update the supplied properties recursively. /// <param name="properties">The properties to be updated.</param> /// </summary> static void UpdatePropertiesRecursively (SerializedNodeProperty[] properties) { // Call Update in properties data for (int i = 0; i < properties.Length; i++) { properties[i].Update(); if (properties[i].hasChildren) UpdatePropertiesRecursively(properties[i].children); } }
/// <summary> /// Set the children of the property. /// </summary> public void SetChildren (SerializedNodeProperty[] children) { m_Children = children; }
/// <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--; } } }
/// <summary> /// Draw the property pop-up. /// </summary> public override void OnGUI (SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // Create styles? if (s_Styles == null) s_Styles = new ReflectedPropertyDrawer.Styles(); // String if (property.propertyType == NodePropertyType.String) { var popupName = property.value as string ?? string.Empty; // Get the current vaue of the member var memberName = property.value as string ?? string.Empty; var attr = this.attribute as ReflectedPropertyAttribute; UnityEngine.Object obj = null; Component component = null; SerializedNodeProperty componentProperty = null; SerializedNodeProperty isStaticProperty = null; // Get the path string path = property.path; int lastDotIndex = path.LastIndexOf('.'); if (lastDotIndex > -1) path = path.Remove(lastDotIndex + 1, path.Length - lastDotIndex - 1); else path = string.Empty; // Get the property iterator NodePropertyIterator iterator = property.serializedNode.GetIterator(); // Get the game object if (iterator.Find(path + attr.objectPropertyPath)) { SerializedNodeProperty objectProperty = iterator.current; obj = objectProperty.value as UnityEngine.Object; } // Get the isStatic property if (iterator.Find(path + attr.isStaticPropertyPath)) { isStaticProperty = iterator.current; if ((bool) isStaticProperty.value) popupName += " (static)"; } // Get the component if (iterator.Find(path + attr.componentPropertyPath)) { componentProperty = iterator.current; component = componentProperty.value as Component; } // Update popup name if (string.IsNullOrEmpty(memberName)) popupName = "No Property"; else if (component != null) popupName = component.GetType().Name + "." + popupName; else if (obj != null) popupName = obj.GetType().Name + "." + popupName; else popupName = "No Property"; // Get the target type System.Type targetType = null; if (component != null) targetType = component.GetType(); else if (obj != null) targetType = obj.GetType(); // Draw Prefix Label if (!FieldUtility.HasMember(targetType, memberName)) { EditorStyles.label.normal.textColor = Color.red; } var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup); var id = GUIUtility.GetControlID(FocusType.Passive); var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent); bool oldGUIEnabled = GUI.enabled; GUI.enabled = obj != null; if (GUI.Button(popupRect, string.IsNullOrEmpty(popupName) ? "No Property" : popupName, EditorStyles.popup) && obj != null && componentProperty != null && isStaticProperty != null) { var menu = new GenericMenu(); // Unique names in the menu var uniqueNames = new List<string>(); uniqueNames.Add("No Property"); // Add none menu.AddItem(new GUIContent("No Property"), popupName == "No Property", delegate () {componentProperty.value = null; isStaticProperty.value = false; property.value = string.Empty;}); // Add separator menu.AddSeparator(string.Empty); string staticName = obj.GetType().Name + "/Static Properties/"; // Add Object static members var members = FieldUtility.GetPublicMembers(obj.GetType(), attr.propertyType, true, true, true); if (members.Length > 0) { for (int i = 0; i < members.Length; i++) { var currentMemberName = members[i].Name; menu.AddItem(new GUIContent(staticName + currentMemberName), component == null && currentMemberName == memberName, delegate () {componentProperty.value = null; isStaticProperty.value = true; property.value = currentMemberName;}); } } // Add Object members members = FieldUtility.GetPublicMembers(obj.GetType(), attr.propertyType, false, true, true); for (int i = 0; i < members.Length; i++) { var currentMemberName = members[i].Name; menu.AddItem(new GUIContent(obj.GetType().Name + "/" + currentMemberName), component == null && currentMemberName == memberName, delegate () {componentProperty.value = null; isStaticProperty.value = false; property.value = currentMemberName;}); } // Add components var gameObject = obj as GameObject; if (gameObject != null) { Component[] components = gameObject.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { // Get the current componet Component currentComponent = components[i]; // Get the component type System.Type componentType = currentComponent.GetType(); // Get a unique name for the component names string componentName = StringHelper.GetUniqueNameInList(uniqueNames, componentType.Name); uniqueNames.Add(componentName); // Add static members staticName = componentName + "/Static Properties/"; members = FieldUtility.GetPublicMembers(currentComponent.GetType(), attr.propertyType, true, true, true); if (members.Length > 0) { for (int j = 0; j < members.Length; j++) { var currentMemberName = members[j].Name; menu.AddItem(new GUIContent(staticName + currentMemberName), currentComponent == component && currentMemberName == memberName, delegate () {componentProperty.value = currentComponent; isStaticProperty.value = true; property.value = currentMemberName;}); } } // Get members members = FieldUtility.GetPublicMembers(currentComponent.GetType(), attr.propertyType, false, true, true); // Add members for (int j = 0; j < members.Length; j++) { var currentMemberName = members[j].Name; menu.AddItem(new GUIContent(componentName + "/" + currentMemberName), currentComponent == component && currentMemberName == memberName, delegate () {componentProperty.value = currentComponent; isStaticProperty.value = false; property.value = currentMemberName;}); } } } menu.ShowAsContext(); } // Restore olde gui enabled GUI.enabled = oldGUIEnabled; // Restore label color EditorStyles.label.normal.textColor = s_Styles.labelTextColor; } // Not String else EditorGUILayout.LabelField(guiContent, new GUIContent("Use UnityObjectReflectProperty with string.")); }
/// <summary> /// Override this method to make your own GUI for the property. /// </summary> public abstract void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent);
/// <summary> /// The custom inspector. /// </summary> public override void OnInspectorGUI() { DrawDefaultInspector(); var randomChild = target as RandomChild; if (randomChild != null) { // Get children nodes ActionNode[] children = randomChild.children; // Update serialized node data if (Event.current.type == EventType.Layout) { this.serializedNode.Update(); } // Get an iterator var iterator = serializedNode.GetIterator(); // Cache the indent level int indentLevel = EditorGUI.indentLevel; if (iterator.Find("weight")) { SerializedNodeProperty current = iterator.current; // Cache the depth of array name int depth = iterator.depth; // Don't draw the size iterator.Next(true); // The current index of the child int childIndex = 0; // Draw children weight while (iterator.Next(iterator.current == null || iterator.current.propertyType != NodePropertyType.Variable) && iterator.depth > depth) { current = iterator.current; if (!current.hideInInspector) { EditorGUI.indentLevel = indentLevel + iterator.depth - 1; // Its an array element of weight array? if (iterator.depth - depth == 1 && childIndex < children.Length) { GUILayoutHelper.DrawNodeProperty(new GUIContent(children[childIndex++].name + " Weight", current.tooltip), current, target); } else { GUILayoutHelper.DrawNodeProperty(new GUIContent(current.label, current.tooltip), current, target); } } } } // Restore the indent level EditorGUI.indentLevel = indentLevel; // Apply modified properties this.serializedNode.ApplyModifiedProperties(); } }
/// <summary> /// The custom inspector. /// </summary> public override void OnInspectorGUI() { int i = 0; ////// RESTORE SAVED ////// //restore and delete clipboard mecanimNode = target as MecanimNode; if (mecanimNode != null) { Motion motion = null; ////////////////////////////////////////////////////////////// /// PRESEVE RESTORE // if (EditorApplication.isPlaying || EditorApplication.isPaused) { if (GUILayout.Button ("Preserve")) { serializedNode.ApplyModifiedProperties (); UnityVariable.SetDirty (mecanimNode.blendX); UnityVariable.SetDirty (mecanimNode.blendY); UnityVariable.SetDirty (mecanimNode.motionOverride); // if (variablesBindedToCurves != null) { // UnityVariable[] varArray = variablesBindedToCurves; // // int varNumber = varArray.Length; // for (int varCurrent=0; varCurrent<varNumber; varCurrent++) { // varArray [varCurrent].OnBeforeSerialize (); // // } // } EditorUtilityEx.Clipboard.preserve (mecanimNode.instanceID, mecanimNode, mecanimNode.GetType ().GetFields ()); } } else { if (EditorUtilityEx.Clipboard.HasBeenPreseved (mecanimNode.instanceID) && GUILayout.Button ("Apply Playmode Changes")) { EditorUtilityEx.Clipboard.restore (mecanimNode.instanceID, mecanimNode); animatorStateSerialized = null; NodePropertyIterator iterator = serializedNode.GetIterator (); while (iterator.Next (true)) { if (iterator.current.value is UnityVariable) { //Debug.Log("OnBeforeDeserialize:"+((UnityVariable)iterator.current.value).Value); ((UnityVariable)iterator.current.value).OnAfterDeserialize (); //Debug.Log("OnAfterDeserialize:"+((UnityVariable)iterator.current.value).Value); } else if (iterator.current.value is UnityVariable[]) { UnityVariable[] varArray = (UnityVariable[])iterator.current.value; int varNumber = varArray.Length; for (int varCurrent=0; varCurrent<varNumber; varCurrent++) { varArray [varCurrent].OnAfterDeserialize (); } } iterator.current.ValueChanged (); this.serializedNode.Update (); iterator.current.ApplyModifiedValue (); } } } ////////////////////// if (Event.current.type == EventType.Layout) { this.serializedNode.Update (); } DrawDefaultInspector (); // // if (EditorGUILayoutEx.ANIMATION_STYLES == null) // EditorGUILayoutEx.ANIMATION_STYLES = new EditorGUILayoutEx.AnimationStyles (); /////////////////////////////// ANIMATOR STATE ///////////////////////////////// if (animatorStateSerialized == null) { NodePropertyIterator iterator = this.serializedNode.GetIterator (); if (iterator.Find ("animatorStateSelected")) animatorStateSerialized = iterator.current; if (iterator.Find ("motionOverride")) motionOverrideSerialized = iterator.current; } ////////// MOTION OVERRIDE HANDLING ////////// if (animatorStateSerialized.value != null) { UnityVariable motionOverridVariable = (UnityVariable)motionOverrideSerialized.value; //if there are no override use motion of selected AnimationState //Debug.Log(((UnityEngine.Object)mecanimNode.motionOverride.Value).); if (motionOverridVariable == null || motionOverridVariable.Value == null || motionOverridVariable.ValueType != typeof(AnimationClip)) motion = ((ws.winx.unity.AnimatorState)animatorStateSerialized.value).motion; else // motion = (Motion)motionOverridVariable.Value; if (motionOverridVariable != null && motionOverridVariable.Value != null && ((ws.winx.unity.AnimatorState)animatorStateSerialized.value).motion == null) { Debug.LogError ("Can't override state that doesn't contain motion"); } } /////////////////////////////////////////////////// if (GUILayout.Button ("BindEditor") && motion!=null) { MecanimNodeEditorWindow.Show ( mecanimNode.self, motion as AnimationClip, this.serializedNode, null); } ///////////// TIME CONTROL OF ANIMATION (SLIDER) ///////// if (Application.isPlaying) { if (animatorStateRuntimeControlEnabledSerialized == null) { NodePropertyIterator iterator = this.serializedNode.GetIterator (); if (iterator.Find ("animationRunTimeControlEnabled")) { animatorStateRuntimeControlEnabledSerialized = iterator.current; } if (iterator.Find ("animatorStateRunTimeControl")) { animatorStateRunTimeControlSerialized = iterator.current; } } if (animatorStateRuntimeControlEnabledSerialized != null && animatorStateRunTimeControlSerialized != null && (bool)animatorStateRuntimeControlEnabledSerialized.value) { Rect timeControlRect = GUILayoutUtility.GetRect (Screen.width - 16f, 26f); timeControlRect.xMin += 38f; timeControlRect.xMax -= 70f; animatorStateRunTimeControlSerialized.value = EditorGUILayoutEx.CustomHSlider (timeControlRect, (float)animatorStateRunTimeControlSerialized.value, 0f, 1f,EditorGUILayoutEx.ANIMATION_STYLES.timeScrubber); } } /////////////////////////////////////////////////////////////// /////////// AVATAR Preview GUI //////////// if (!Application.isPlaying && motion != null) { //This makes layout to work (Reserving space) Rect avatarRect = GUILayoutUtility.GetRect (Screen.width - 16f, 200); avatarRect.width -= 70f; avatarRect.xMin += 6f; if (avatarPreview == null) avatarPreview = new AvatarPreviewW (null, motion); else avatarPreview.SetPreviewMotion (motion); EditorGUILayout.BeginHorizontal (); if (eventTimeValues != null && Event.current.type == EventType.Repaint) { //find first selected if exist int eventTimeValueSelectedIndex = Array.IndexOf (eventTimeValuesSelected, true); if (eventTimeValueSelectedIndex > -1) { avatarPreview.SetTimeAt (eventTimeValues [eventTimeValueSelectedIndex]); } else { //!!! changing //avatarPreview.timeControl.startTime // start/stop makes AvatarPreview to play from start to stop // and the rest of animation isn't visible in Timeline so not good for selecting range // but its not offer good usability of resized animation if (avatarPreview.timeControl.playing) { //restrict animation into this range if (avatarPreview.timeControl.normalizedTime < mecanimNode.range.rangeStart || avatarPreview.timeControl.normalizedTime > mecanimNode.range.rangeEnd) { avatarPreview.timeControl.nextCurrentTime = avatarPreview.timeControl.startTime * (1f - mecanimNode.range.rangeStart) + avatarPreview.timeControl.stopTime * mecanimNode.range.rangeStart; } } else { //set AvatarPreview animation time range depending of drag of range control handles if (Math.Abs (mecanimNode.range.rangeStart - timeNormalizedStartPrev) > 0.01f) { timeNormalizedStartPrev = mecanimNode.range.rangeStart; avatarPreview.SetTimeAt (timeNormalizedStartPrev); } else if (Math.Abs (mecanimNode.range.rangeEnd - timeNormalizedEndPrev) > 0.01f) { timeNormalizedEndPrev = mecanimNode.range.rangeEnd; avatarPreview.SetTimeAt (timeNormalizedEndPrev); } } } } avatarPreview.timeControl.playbackSpeed = mecanimNode.speed; avatarPreview.DoAvatarPreview (avatarRect, GUIStyle.none); //Debug.Log(avatarPreview.timeControl.currentTime+" "+); EditorGUILayout.EndHorizontal (); ////////// Events Timeline GUI ////////// if (!eventTimeLineInitalized) { //TODO calculate PopupRect eventTimeLineValuePopUpRect = new Rect ((Screen.width - 250) * 0.5f, (Screen.height - 150) * 0.5f, 250, 150); //select the time values from nodes //eventTimeValues = mecanimNode.children.Select ((val) => (float)((SendEventNormalized)val).timeNormalized.Value).ToArray (); eventTimeValues = mecanimNode.children.Select ((val) => (float)((SendEventNormalizedNode)val).timeNormalized.serializedProperty.floatValue).ToArray (); eventDisplayNames = mecanimNode.children.Select ((val) => ((SendEventNormalizedNode)val).name).ToArray (); eventTimeValuesSelected = new bool[eventTimeValues.Length]; playButtonStyle = "TimeScrubberButton"; if (playButtonStyle != null) playButtonSize = playButtonStyle.CalcSize (new GUIContent ()); eventTimeLineInitalized = true; } Rect timeLineRect = GUILayoutUtility.GetRect (Screen.width - 16f, 50f); //Rect timeLineRect = GUILayoutUtility.GetLastRect (); Texture eventMarkerTexture = EditorGUILayoutEx.ANIMATION_STYLES.eventMarker.image; timeLineRect.xMin += playButtonSize.x - eventMarkerTexture.width * 0.5f; timeLineRect.xMax -= eventMarkerTexture.width * 0.5f; //timeLineRect.height = EditorGUILayoutEx.eventMarkerTexture.height * 3 * 0.66f + playButtonSize.y; timeLineRect.width -= 66f; EditorGUILayoutEx.CustomTimeLine (ref timeLineRect,new GUIContent(eventMarkerTexture), ref eventTimeValues, ref eventTimeValuesPrev, ref eventDisplayNames, ref eventTimeValuesSelected, avatarPreview.timeControl.normalizedTime, onMecanimEventAdd, onMecanimEventDelete, onMecanimEventClose, onMecanimEventEdit, onMecanimEventDragEnd ); EditorGUILayout.LabelField ("Events Timeline"); SendEventNormalizedNode ev; //update time values int eventTimeValuesNumber = mecanimNode.children.Length; for (i=0; i<eventTimeValuesNumber; i++) { ev = ((SendEventNormalizedNode)mecanimNode.children [i]); //ev.timeNormalized.Value = eventTimeValues [i]; ev.timeNormalized.Value = eventTimeValues [i]; //if changes have been made in pop editor or SendEventNormailized inspector if (ev.name != eventDisplayNames [i]) eventDisplayNames [i] = ((SendEventNormalizedNode)mecanimNode.children [i]).name; ev.timeNormalized.ApplyModifiedProperties (); } // Restore the indent level //EditorGUI.indentLevel = indentLevel; // Apply modified properties this.serializedNode.ApplyModifiedProperties (); } } }
// // Methods // /// <summary> /// Handles the onGUI event. /// </summary> /// <param name="property">Property.</param> /// <param name="node">Node.</param> /// <param name="guiContent">GUI content.</param> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { //if (animatorSerialized == null || aniController == null) { if(aniController == null) { //!!! Serialization never serialized Animator cos its initialized in Reset after // NodePropertyIterator iter= property.serializedNode.GetIterator(); // iter.Find(attribute.animatorFieldName); // animatorSerialized=iter.current; // // if(animatorSerialized==null || animatorSerialized.value==null){ // Debug.LogError("AnimatorStateNodePropertyDrawer> No Animator component set on node parent GameObject"); // return; // } //runtimeContoller =( (Animator)animatorSerialized.value).runtimeAnimatorController; Animator animator = node.GetType ().GetField (attribute.animatorFieldName).GetValue (node) as Animator; RuntimeAnimatorController runtimeContoller; runtimeContoller = animator.runtimeAnimatorController; if (runtimeContoller is AnimatorOverrideController) aniController = ((AnimatorOverrideController)runtimeContoller).runtimeAnimatorController as UnityEditor.Animations.AnimatorController; else aniController = runtimeContoller as UnityEditor.Animations.AnimatorController; } animatorStateDisplayOptions = MecanimUtility.GetDisplayOptions (aniController); animatorStateValues = MecanimUtility.GetAnimatorStates (aniController); if(property.value!=null){ if(animatorStateValues.Length>0){ animatorStateSelectedPrev=animatorStateSelected=animatorStateValues.FirstOrDefault((itm)=>itm.nameHash==((ws.winx.unity.AnimatorState)property.value).nameHash); } } animatorStateSelected = EditorGUILayoutEx.CustomObjectPopup (guiContent, animatorStateSelected, animatorStateDisplayOptions, animatorStateValues);//,compare); //TODO try Begin/End Check if (animatorStateSelectedPrev != animatorStateSelected) { NodePropertyIterator iter = property.serializedNode.GetIterator (); iter.Find (attribute.layerIndexFieldName); SerializedNodeProperty layerIndexSerialized = iter.current; layerIndexSerialized.value = MecanimUtility.GetLayerIndex (aniController, animatorStateSelected); layerIndexSerialized.ApplyModifiedValue (); ws.winx.unity.AnimatorState state=property.value as ws.winx.unity.AnimatorState; if(state==null) state=ScriptableObject.CreateInstance<ws.winx.unity.AnimatorState>(); state.motion=animatorStateSelected.motion; state.nameHash=animatorStateSelected.nameHash; state.layer=(int)layerIndexSerialized.value; if(state.motion is UnityEditor.Animations.BlendTree){ BlendTree tree =(BlendTree)state.motion; int blendParamsNum= tree.GetRecursiveBlendParamCount(); state.blendParamsHashes=new int[blendParamsNum]; for(int i=0;i<blendParamsNum;i++) state.blendParamsHashes[i]=Animator.StringToHash(tree.GetRecursiveBlendParam(i)); }else{ state.blendParamsHashes=null; } //property.value=state; property.ValueChanged(); property.ApplyModifiedValue (); animatorStateSelectedPrev = animatorStateSelected; } if (animatorStateSelected.motion == null) Debug.LogError ("Selected state doesn't have Motion set"); }
/// <summary> /// Draw the TextArea. /// </summary> public override void OnGUI (SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // The text to display string text; // string if (property.propertyType == NodePropertyType.String) { // Get the text text = property.value as string ?? string.Empty; } // StringVar else if (property.propertyType == NodePropertyType.Variable && property.type == typeof(StringVar)) { // Get the text var stringVar = property.value as StringVar; if (stringVar != null) text = stringVar.Value as string ?? string.Empty; else text = string.Empty; } // Not supported else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use TextAreaAttribute with string or StringVar.")); return; } // Create style? if (s_Styles == null) s_Styles = new NodeTextAreaDrawer.Styles(); // Get the text area var textAreaAttr = (NodeTextAreaAttribute) attribute; // Store the current content color Color contentColor = GUI.contentColor; // The text is empty? if (string.IsNullOrEmpty(text)) { text = textAreaAttr.hint; Color textColor = EditorStyles.label.normal.textColor; textColor.a = .5f; GUI.contentColor = textColor; } // Draw the text area. EditorGUI.BeginChangeCheck (); #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 string value = EditorGUILayout.TextArea (text, s_Styles.textArea, GUILayout.Height(16f * textAreaAttr.lines)); #else string value = EditorGUILayout.TextArea (text, s_Styles.textArea, GUILayout.Height(EditorGUIUtility.singleLineHeight * textAreaAttr.lines)); #endif // Check for changes if (EditorGUI.EndChangeCheck ()) { if (property.propertyType == NodePropertyType.String) property.value = value; else { // Get the text var stringVar = property.value as StringVar; if (stringVar != null) { stringVar.Value = value; property.ValueChanged(); } } } // Restore content color GUI.contentColor = contentColor; }
/// <summary> /// Draw the property pop-up. /// </summary> public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // Create styles? if (s_Styles == null) { s_Styles = new ReflectedPropertyDrawer.Styles(); } // String if (property.propertyType == NodePropertyType.String) { var popupName = property.value as string ?? string.Empty; // Get the current vaue of the member var memberName = property.value as string ?? string.Empty; var attr = this.attribute as ReflectedPropertyAttribute; UnityEngine.Object obj = null; Component component = null; SerializedNodeProperty componentProperty = null; SerializedNodeProperty isStaticProperty = null; // Get the path string path = property.path; int lastDotIndex = path.LastIndexOf('.'); if (lastDotIndex > -1) { path = path.Remove(lastDotIndex + 1, path.Length - lastDotIndex - 1); } else { path = string.Empty; } // Get the property iterator NodePropertyIterator iterator = property.serializedNode.GetIterator(); // Get the game object if (iterator.Find(path + attr.objectPropertyPath)) { SerializedNodeProperty objectProperty = iterator.current; obj = objectProperty.value as UnityEngine.Object; } // Get the isStatic property if (iterator.Find(path + attr.isStaticPropertyPath)) { isStaticProperty = iterator.current; if ((bool)isStaticProperty.value) { popupName += " (static)"; } } // Get the component if (iterator.Find(path + attr.componentPropertyPath)) { componentProperty = iterator.current; component = componentProperty.value as Component; } // Update popup name if (string.IsNullOrEmpty(memberName)) { popupName = "No Property"; } else if (component != null) { popupName = component.GetType().Name + "." + popupName; } else if (obj != null) { popupName = obj.GetType().Name + "." + popupName; } else { popupName = "No Property"; } // Get the target type System.Type targetType = null; if (component != null) { targetType = component.GetType(); } else if (obj != null) { targetType = obj.GetType(); } // Draw Prefix Label if (!FieldUtility.HasMember(targetType, memberName)) { EditorStyles.label.normal.textColor = Color.red; } var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup); var id = GUIUtility.GetControlID(FocusType.Passive); var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent); bool oldGUIEnabled = GUI.enabled; GUI.enabled = obj != null; if (GUI.Button(popupRect, string.IsNullOrEmpty(popupName) ? "No Property" : popupName, EditorStyles.popup) && obj != null && componentProperty != null && isStaticProperty != null) { var menu = new GenericMenu(); // Unique names in the menu var uniqueNames = new List <string>(); uniqueNames.Add("No Property"); // Add none menu.AddItem(new GUIContent("No Property"), popupName == "No Property", delegate() { componentProperty.value = null; isStaticProperty.value = false; property.value = string.Empty; }); // Add separator menu.AddSeparator(string.Empty); string staticName = obj.GetType().Name + "/Static Properties/"; // Add Object static members var members = FieldUtility.GetPublicMembers(obj.GetType(), attr.propertyType, true, true, true); if (members.Length > 0) { for (int i = 0; i < members.Length; i++) { var currentMemberName = members[i].Name; menu.AddItem(new GUIContent(staticName + currentMemberName), component == null && currentMemberName == memberName, delegate() { componentProperty.value = null; isStaticProperty.value = true; property.value = currentMemberName; }); } } // Add Object members members = FieldUtility.GetPublicMembers(obj.GetType(), attr.propertyType, false, true, true); for (int i = 0; i < members.Length; i++) { var currentMemberName = members[i].Name; menu.AddItem(new GUIContent(obj.GetType().Name + "/" + currentMemberName), component == null && currentMemberName == memberName, delegate() { componentProperty.value = null; isStaticProperty.value = false; property.value = currentMemberName; }); } // Add components var gameObject = obj as GameObject; if (gameObject != null) { Component[] components = gameObject.GetComponents <Component>(); for (int i = 0; i < components.Length; i++) { // Get the current componet Component currentComponent = components[i]; // Get the component type System.Type componentType = currentComponent.GetType(); // Get a unique name for the component names string componentName = StringHelper.GetUniqueNameInList(uniqueNames, componentType.Name); uniqueNames.Add(componentName); // Add static members staticName = componentName + "/Static Properties/"; members = FieldUtility.GetPublicMembers(currentComponent.GetType(), attr.propertyType, true, true, true); if (members.Length > 0) { for (int j = 0; j < members.Length; j++) { var currentMemberName = members[j].Name; menu.AddItem(new GUIContent(staticName + currentMemberName), currentComponent == component && currentMemberName == memberName, delegate() { componentProperty.value = currentComponent; isStaticProperty.value = true; property.value = currentMemberName; }); } } // Get members members = FieldUtility.GetPublicMembers(currentComponent.GetType(), attr.propertyType, false, true, true); // Add members for (int j = 0; j < members.Length; j++) { var currentMemberName = members[j].Name; menu.AddItem(new GUIContent(componentName + "/" + currentMemberName), currentComponent == component && currentMemberName == memberName, delegate() { componentProperty.value = currentComponent; isStaticProperty.value = false; property.value = currentMemberName; }); } } } menu.ShowAsContext(); } // Restore olde gui enabled GUI.enabled = oldGUIEnabled; // Restore label color EditorStyles.label.normal.textColor = s_Styles.labelTextColor; } // Not String else { EditorGUILayout.LabelField(guiContent, new GUIContent("Use UnityObjectReflectProperty with string.")); } }
/// <summary> /// Draw the property pop-up. /// </summary> public override void OnGUI (SerializedNodeProperty property, ActionNode node, GUIContent guiContent) { // String if (property.propertyType == NodePropertyType.String) { var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup); var id = GUIUtility.GetControlID(FocusType.Passive); var popupRect = EditorGUI.PrefixLabel(rect, id, guiContent); var popupName = property.value as string ?? string.Empty; var propertyOrField = node as PropertyOrField; var oldGUIColor = GUI.color; if (propertyOrField.propertyType == null) GUI.color = Color.red; if (GUI.Button(popupRect, string.IsNullOrEmpty(popupName) ? "None" : popupName, EditorStyles.popup)) { var isSetProperty = propertyOrField is SetProperty; var members = FieldUtility.GetPublicMembers(propertyOrField.targetObject.ObjectType, null, false, isSetProperty, !isSetProperty); var menu = new GenericMenu(); // Add none menu.AddItem(new GUIContent("None"), string.IsNullOrEmpty(popupName), delegate () {property.value = string.Empty;}); // Add members for (int i = 0; i < members.Length; i++) { var memberName = members[i].Name; menu.AddItem(new GUIContent(memberName), popupName == memberName, delegate () {property.value = memberName;}); } menu.ShowAsContext(); } GUI.color = oldGUIColor; } // Not String else EditorGUILayout.LabelField(guiContent, new GUIContent("Use UnityObjectProperty with string.")); }