// // 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(); }
// // 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(); }
public new void DrawDefaultInspector() { NodePropertyIterator iterator = this.serializedNode.GetIterator(); 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) { if (current.path == "motionOverride" && mecanimNode != null && mecanimNode.animatorStateSelected != null && mecanimNode.animatorStateSelected.motion != null && mecanimNode.animatorStateSelected.motion is BlendTree) { continue; } if (current.path == "blendX" && mecanimNode != null && mecanimNode.animatorStateSelected != null && (mecanimNode.animatorStateSelected.motion == null || !(mecanimNode.animatorStateSelected.motion is BlendTree && !String.IsNullOrEmpty(((BlendTree)mecanimNode.animatorStateSelected.motion).blendParameter)) )) { continue; } if (current.path == "blendY" && mecanimNode != null && mecanimNode.animatorStateSelected != null && (mecanimNode.animatorStateSelected.motion == null || !(mecanimNode.animatorStateSelected.motion is BlendTree && !String.IsNullOrEmpty(((BlendTree)mecanimNode.animatorStateSelected.motion).blendParameterY)) )) { continue; } EditorGUI.indentLevel = indentLevel + iterator.depth; GUILayoutHelper.DrawNodeProperty(new GUIContent(current.label, current.tooltip), current, mecanimNode, null, true); } } EditorGUI.indentLevel = indentLevel; this.serializedNode.ApplyModifiedProperties(); }
// // 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(); }
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(); } }
// // 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> /// 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 as 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; } EditorUtilityEx.ApplySerializedPropertyChangeTo(ev.timeNormalized); //ev.timeNormalized.ApplyModifiedProperties (); } // Restore the indent level //EditorGUI.indentLevel = indentLevel; // Apply modified properties this.serializedNode.ApplyModifiedProperties(); } } }
/// <summary> /// The custom inspector. /// </summary> public override void OnInspectorGUI() { //why is this line for??? // if (Event.current.type == EventType.Layout) { // this.serializedNode.Update (); // // } bool isAnalogInput = false; bool isFullAxis = false; NodePropertyIterator iterator = this.serializedNode.GetIterator(); if (iterator.Find("inputType")) { isAnalogInput = (GetInputNode.InputType)iterator.current.value == GetInputNode.InputType.GetInput; } if (isAnalogInput && iterator.Find("fullAxis")) { isFullAxis = (bool)iterator.current.value; } iterator = this.serializedNode.GetIterator(); 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) { if (!isAnalogInput) { if ( current.path == "sensitivity" || current.path == "dreadzone" || current.path == "gravity" || current.path == "multiplier" || current.path == "variable" || current.path == "fullAxis" || current.path == "inputStateNeg" ) { continue; } } else if (!isFullAxis && current.path == "inputStateNeg") { continue; } EditorGUI.indentLevel = indentLevel + iterator.depth; GUILayoutHelper.DrawNodeProperty(new GUIContent(current.label, current.tooltip), current, this.target, null, true); } } EditorGUI.indentLevel = indentLevel; this.serializedNode.ApplyModifiedProperties(); }
/// <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(); }
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(); }