/// <summary> /// Adds the unity variable of type to list. /// </summary> /// <param name="name">Name.</param> /// <param name="type">Type.</param> /// <param name="drawer">Drawer.</param> void AddUnityVariableOfTypeToList(String name, Type type, PropertyDrawer drawer = null) { ReorderableList list = __variablesReordableList; var index = list.serializedProperty.arraySize; list.serializedProperty.arraySize++; list.index = index; UnityVariable variable = UnityVariable.CreateInstanceOf(type); variable.name = name; variable.drawer = drawer; // UnityVariable variable = (UnityVariable)ScriptableObject.CreateInstance<UnityVariable> (); // variable.name = name; // variable.drawer = drawer; // variable.Value = value; var element = list.serializedProperty.GetArrayElementAtIndex(index); element.objectReferenceValue = variable; serializedObject.ApplyModifiedProperties(); }
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { UnityVariable variable = property.objectReferenceValue as UnityVariable; if (variable != null && variable.serializedProperty != null) { SerializedProperty variableSerializadProperty = variable.serializedProperty as SerializedProperty; if (variable.ValueType == typeof(UnityEvent)) { SerializedProperty elements = variableSerializadProperty.FindPropertyRelative("m_PersistentCalls.m_Calls"); return(Math.Max(1, elements.arraySize) * 43 + 36f + 2f + EditorGUIUtility.singleLineHeight); //16f label height , 2f separator } else if ((variable.ValueType.IsGenericType && variable.ValueType.GetGenericTypeDefinition() == typeof(List <>) ) || variable.ValueType.IsArray) { if (variableSerializadProperty.isExpanded) { return(EditorGUIUtility.singleLineHeight + (variableSerializadProperty.arraySize + 1) * EditorGUIUtility.singleLineHeight + 2f); //label + (size label) + list elements } } else if (variable.ValueType.IsGenericType && variable.ValueType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { return(Math.Max(1, variableSerializadProperty.arraySize) * 43 + 36f + 2f + EditorGUIUtility.singleLineHeight); //16f label height , 2f separator } } return(base.GetPropertyHeight(property, label)); }
public static void Show(UnityVariable variable) { if (variable.Value == null || variable.ValueType == typeof(UnityEngine.Object)) return; EditorWindow.GetWindow<UnityObjectEditorWindow> (); __variable = variable; }
/// <summary> /// Applies the variable value to serialized property. /// </summary> /// <param name="variable">Variable.</param> public static void UpdateSerializedProperty(UnityVariable variable) { SerializedProperty serializedProperty = variable.serializedProperty as SerializedProperty; object value = variable.Value; if (variable.ValueType == typeof(float)) { serializedProperty.floatValue = (float)value; } else if (variable.ValueType == typeof(bool)) { serializedProperty.boolValue = (bool)value; } else if (variable.ValueType == typeof(Bounds)) { serializedProperty.boundsValue = (Bounds)value; } else if (variable.ValueType == typeof(Color)) { serializedProperty.colorValue = (Color)value; } else if (variable.ValueType == typeof(Rect)) { serializedProperty.rectValue = (Rect)value; } else if (variable.ValueType == typeof(int)) { serializedProperty.intValue = (int)value; } else if (variable.ValueType == typeof(Vector3)) { serializedProperty.vector3Value = (Vector3)value; } else if (variable.ValueType == typeof(string)) { serializedProperty.stringValue = (string)value; } else if (variable.ValueType == typeof(Quaternion)) { serializedProperty.quaternionValue = (Quaternion)value; } else if (value is UnityEngine.Object) { serializedProperty.objectReferenceValue = value as UnityEngine.Object; } //TODO apply changes of array,list,dict happen in code, to serialized prop so can be shown in editor }
// void Update(){ // // // } void Reset() { // variable = UnityVariable.CreateInstanceOf (typeof(string)); // variable1 = UnityVariable.CreateInstanceOf (typeof(Color)); // variable2 = UnityVariable.CreateInstanceOf (typeof(Bounds)); // variable3 = UnityVariable.CreateInstanceOf (typeof(Quaternion)); // variable4 = UnityVariable.CreateInstanceOf (typeof(AnimationCurve)); // variable5 = UnityVariable.CreateInstanceOf (typeof(Light)); variable6 = UnityVariable.CreateInstanceOf (typeof(float)); }
public static void Show(UnityVariable variable) { if (variable.Value == null || variable.ValueType == typeof(UnityEngine.Object)) { return; } EditorWindow.GetWindow <UnityVariableEditorWindow> (); __variable = variable; }
public override void Reset() { //!!! if UnityVariables aren't Init here KABOOM when added to MecaniNode this.timeNormalized = UnityVariable.CreateInstanceOf (typeof(float)); //this.unityEvent = (UnityVariable)ScriptableObject.CreateInstance< UnityVariable> (); //this.unityEvent.Value = new UnityEvent (); //this.unityEvent.OnBeforeSerialize (); this.unityEvent = UnityVariable.CreateInstanceOf (typeof(UnityEngine.Events.UnityEvent)); _timeNormalizedLast = 0f; }
void onSelectCallback(ReorderableList list) { UnityVariable variable = list.serializedProperty.GetArrayElementAtIndex(list.index).objectReferenceValue as UnityVariable; //show popup just for complex types and UnityEvent if (variable != null && (Array.IndexOf(EditorGUILayoutEx.unityTypes, variable.ValueType) < 0 || variable.ValueType == typeof(UnityEvent)) ) { UnityVariableEditorWindow.Show(variable); } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { 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 = Type.GetType(property.type); //create types selection popup //if ( selectedType == typeof(System.Object)) { if (property.objectReferenceValue == null) { type = EditorGUILayoutEx.unityTypes [0]; } else { type = ((UnityVariable)property.objectReferenceValue).ValueType; } String name = ((UnityVariable)property.objectReferenceValue).name; bool typeChanged = false; EditorGUI.BeginChangeCheck(); typeSelected = EditorGUILayoutEx.CustomObjectPopup <Type> (null, type, EditorGUILayoutEx.unityTypesDisplayOptions, EditorGUILayoutEx.unityTypes, null, null, null, null, typePos); //if change of type create new variable if (typeSelected != type && !typeSelected.IsSubclassOf(type) /*&& type!=typeof(UnityEngine.Object)*/) { property.objectReferenceValue = UnityVariable.CreateInstanceOf(typeSelected); typeChanged = true; } // } property.objectReferenceValue = EditorGUILayoutEx.UnityVariablePopup(null, property.objectReferenceValue as UnityVariable, typeSelected, new List <GUIContent>(), new List <UnityVariable>(), varPos); UnityVariable variable = ((UnityVariable)property.objectReferenceValue); variable.drawer = this; variable.name = name; if (EditorGUI.EndChangeCheck() || typeChanged) { property.serializedObject.ApplyModifiedProperties(); //EditorUtilityEx.ApplySerializedPropertyTo(variable); } }
/// <summary> /// Applies the modified properties serializedProperty so can be used in PropertyDrawers /// </summary> public static void ApplySerializedPropertyChangeTo(UnityVariable variable) { //SerializedObject __seralizedObject = variable.seralizedObject as SerializedObject; SerializedProperty seralizedProperty = variable.serializedProperty as SerializedProperty; if (seralizedProperty.serializedObject != null) { if (seralizedProperty.serializedObject.targetObject == null) //has been destroyed by Unity ???? //__seralizedObject=null; { seralizedProperty = null; variable.serializedProperty = seralizedProperty = SerializeObject(variable); } //__seralizedObject.ApplyModifiedProperties (); seralizedProperty.serializedObject.ApplyModifiedProperties(); object targetObject = seralizedProperty.serializedObject.targetObject; if (variable.ValueType.IsGenericType && variable.ValueType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { IDictionary dict = variable.Value as IDictionary; dict.Clear(); IList valuesList = targetObject.GetType().GetField("values").GetValue(targetObject) as IList; IList keysList = targetObject.GetType().GetField("keys").GetValue(targetObject) as IList; int cnt = valuesList.Count; for (int i = 0; i < cnt; i++) { if (!dict.Contains(keysList[i])) { dict.Add(keysList[i], valuesList[i]); } } } else { variable.Value = targetObject.GetType().GetField("value").GetValue(targetObject); } } }
public override void Reset() { variable = UnityVariable.CreateInstanceOf (typeof(float)); //variable.Value = 0f;//make it float type multiplier = 1f; sensitivity = 0.25f; gravity = 0.3f; dreadzone = 0.1f; fullAxis = true; }
public Rect DrawVariables(Rect position, SerializedProperty property) { UnityVariable currentVariable; currentVariable = (UnityVariable)property.objectReferenceValue; if (currentVariable != null) { Type type = currentVariable.ValueType; if (currentVariable.serializedProperty == null) { currentVariable.Value = UnityVariable.Default(type); } //if UnityVariable isn't of type of known unityTypes or it is UnityEvent or have custom Drawer if (Array.IndexOf(EditorGUILayoutEx.unityTypes, type) < 0 || type == typeof(UnityEvent) || (currentVariable.drawer != null)) { //!!! this part is for Any UnityVariable with UnityTypes wiht UniUnityVariablePropertyDrawer (experimental) if (currentVariable.ValueType != typeof(UnityEvent) && currentVariable.drawer != null) { variableNameTextFieldPos.y = position.y; variableNameTextFieldPos.x = position.x; EditorGUI.BeginChangeCheck(); currentVariable.name = EditorGUI.TextField(variableNameTextFieldPos, currentVariable.name); if (EditorGUI.EndChangeCheck()) { property.serializedObject.ApplyModifiedProperties(); //EditorUtility.SetDirty (currentVariable); } position.xMin = variableNameTextFieldPos.xMax + 10; (currentVariable.drawer as PropertyDrawer).OnGUI(position, property, null); } else { currentVariable.name = EditorGUI.TextField(position, currentVariable.name); } } else { PropertyDrawer drawer; drawer = EditorUtilityEx.GetDrawer(type); if (drawer == null) { drawer = EditorUtilityEx.GetDefaultDrawer(); } variableNameTextFieldPos.y = position.y; variableNameTextFieldPos.x = position.x; currentVariable.name = EditorGUI.TextField(variableNameTextFieldPos, currentVariable.name); position.xMin = variableNameTextFieldPos.xMax + 10; //position.width =position.width- variableNameTextFieldPos.width; EditorGUI.BeginChangeCheck(); if (currentVariable.serializedProperty == null) { currentVariable.serializedProperty = EditorUtilityEx.SerializeObject(currentVariable); } drawer.OnGUI(position, currentVariable.serializedProperty as SerializedProperty, new GUIContent("")); if (EditorGUI.EndChangeCheck()) { EditorUtilityEx.ApplySerializedPropertyChangeTo(currentVariable); EditorUtility.SetDirty(currentVariable); } } } return(position); }
public override void Reset() { variable1=UnityVariable.CreateInstanceOf(typeof(float)); variable2=UnityVariable.CreateInstanceOf(typeof(float)); }
public void AddVariable(UnityVariable prop) { variablesList.Add (prop); }
/// <summary> /// Handles the GUI event. /// </summary> void OnGUI() { if (_keyframeMarker == null) { _keyframeMarker = new GUIContent(EditorGUILayoutEx.ANIMATION_STYLES.pointIcon); } if (!Application.isPlaying && __gameObjectClipList != null) { _curvesEditorShow = EditorGUILayout.Foldout(_curvesEditorShow, "Curves"); //int indentLevel = 0; Rect curveEditorRect = new Rect(0, 0, 0, 0); int i = 0; if (_curvesEditorShow) { //This makes layout to work (Reserving space) curveEditorRect = GUILayoutUtility.GetRect(Screen.width - 16f, 200); /////// CURVE EDITOR //////// curveEditorRect.width = curveEditorRect.width - 32f; curveEditorRect.x = 16f; if (curveEditor == null) { CurveWrapperW[] curveWrappers; int numCurves = curves.Length; curveWrappers = new CurveWrapperW[numCurves]; CurveWrapperW curveWrapperNew; for (i = 0; i < numCurves; i++) { curveWrapperNew = new CurveWrapperW(); curveWrapperNew.curve = curves [i]; curveWrapperNew.color = curveColors [i]; curveWrappers [i] = curveWrapperNew; } curveEditor = new CurveEditorW(curveEditorRect, curveWrappers, false); curveEditor.FrameSelected(true, true); curveEditor.scaleWithWindow = true; curveEditor.hSlider = false; curveEditor.hRangeMin = 0f; curveEditor.hRangeMax = 1f; curveEditor.hRangeLocked = true; curveEditor.onSelect += onCurveSelect; } else { curveEditor.rect = curveEditorRect; curveEditor.FrameSelected(false, false); } curveEditor.DoEditor(); /////////////////////////////////////////////////////////////////////////////// ///////////// ADD/REMOVE CURVE BINDED TO OBJECT PROP OR GLOBAL VARIABLE ///////////// /// // EditorGUILayout.BeginHorizontal(); //if curve is selected display curve properties if (_curveIndexSelected > -1 && _curveIndexSelected < variablesBindedToCurves.Length) { UnityVariable variableSelected = variablesBindedToCurves [_curveIndexSelected]; try { bindingCurvesGUIContent.text = variableSelected.instanceBinded.name + "." + variableSelected.memberPath; EditorGUILayout.LabelField(bindingCurvesGUIContent, new GUILayoutOption[] {}); EditorGUI.BeginChangeCheck(); Color colorNew = EditorGUILayout.ColorField(curveColors [_curveIndexSelected]); if (EditorGUI.EndChangeCheck()) { curveEditor.animationCurves [_curveIndexSelected].color = colorNew; curveColors [_curveIndexSelected] = colorNew; curvesColorsSerialized.ValueChanged(); curvesColorsSerialized.ApplyModifiedValue(); } } catch (MissingReferenceException ex) { bindingCurvesGUIContent.text = "Invalid UVariable " + ex.Message; } } else { bindingCurvesGUIContent.text = "Curve binding:"; List <UnityVariable> blackboardLocalList = (MecanimNodeEditorWindow.__serializedNode.target.blackboard as BlackboardCustom).GetVariableBy(typeof(float)); List <GUIContent> displayOptionsList = blackboardLocalList.Select((item) => new GUIContent("Local/" + item.name)).ToList(); __variableSelected = EditorGUILayoutEx.UnityVariablePopup(bindingCurvesGUIContent, __variableSelected, typeof(float), displayOptionsList, blackboardLocalList); _colorSelected = EditorGUILayout.ColorField(_colorSelected); } /////////////// ADD CURVE(+) ///////// if (GUILayout.Button("Add") && __variableSelected != null) { List <UnityVariable> vList = variablesBindedToCurves.ToList(); vList.Add(__variableSelected); variablesBindedToCurvesSerialized.value = variablesBindedToCurves = vList.ToArray(); variablesBindedToCurvesSerialized.ValueChanged(); //variablesBindedToCurvesSerialized.ApplyModifiedValue (); List <Color> cList = curveColors.ToList(); _colorSelected.a = 1; cList.Add(_colorSelected); curvesColorsSerialized.value = curveColors = cList.ToArray(); curvesColorsSerialized.ValueChanged(); //curvesColorsSerialized.ApplyModifiedValue (); AnimationCurve curveAnimationNew; List <AnimationCurve> crList = curves.ToList(); curveAnimationNew = new AnimationCurve(new Keyframe[] { new Keyframe(0f, (float)__variableSelected.Value), new Keyframe(1f, 1f) }); //TODO add from preset crList.Add(curveAnimationNew); curvesSerialized.value = curves = crList.ToArray(); curvesSerialized.ValueChanged(); //curvesColorsSerialized.ApplyModifiedValue (); ///add curve wrapped to CurveEditor CurveWrapperW curveWrapperW = new CurveWrapperW(); curveWrapperW.color = _colorSelected; curveWrapperW.curve = curveAnimationNew; curveEditor.AddCurve(curveWrapperW); curveEditor.FrameSelected(true, true); __serializedNode.Update(); __serializedNode.ApplyModifiedProperties(); __variableSelected = null; } ///////////// DELETE CURVE //////////// if (GUILayout.Button("Del") || Event.current.keyCode == KeyCode.Delete) { curveEditor.RemoveCurveAt(_curveIndexSelected); List <UnityVariable> vList = variablesBindedToCurves.ToList(); vList.RemoveAt(_curveIndexSelected); variablesBindedToCurvesSerialized.value = variablesBindedToCurves = vList.ToArray(); variablesBindedToCurvesSerialized.ValueChanged(); List <Color> cList = curveColors.ToList(); cList.RemoveAt(_curveIndexSelected); curvesColorsSerialized.value = curveColors = cList.ToArray(); curvesColorsSerialized.ValueChanged(); List <AnimationCurve> crList = curves.ToList(); crList.RemoveAt(_curveIndexSelected); curvesSerialized.value = curves = crList.ToArray(); curvesSerialized.ValueChanged(); _curveIndexSelected = -1; __variableSelected = null; __serializedNode.ApplyModifiedProperties(); } EditorGUILayout.EndHorizontal(); } else //NOT CURVE EDITOR ///////////// GAMEOBJECT - CLIP BINDINGS ////////// { __gameObjectClipList.DoLayoutList(); ////////////////////////////////////////////// } EditorGUILayout.Space(); __mecanimNodeClipBinding.clip = __spaceGameObjectAnimationClip; ///////////// TIME CONTROL OF ANIMATION (SLIDER) ///////// Rect timeControlRect = GUILayoutUtility.GetRect(Screen.width, 26f); timeControlRect.xMax = 32f; ///////////// PLAY ANIMATION TOGGLE ///////// __isPlaying = GUI.Toggle(timeControlRect, __isPlaying, !__isPlaying ? EditorGUILayoutEx.ANIMATION_STYLES.playIcon : EditorGUILayoutEx.ANIMATION_STYLES.pauseIcon, EditorGUILayoutEx.ANIMATION_STYLES.playButton); if (__isPlaying) { } else { } timeControlRect.xMin = timeControlRect.xMax + 1f; timeControlRect.xMax = timeControlRect.xMin + 21f; timeControlRect.yMin += 2f; EditorGUI.BeginChangeCheck(); Color color = GUI.color; //save color if (AnimationMode.InAnimationMode()) { GUI.color = AnimationMode.animatedPropertyColor; //change color of record button to red } ///////////// RECORD ANIMATION TOGGLE ///////// __isRecording = GUI.Toggle(timeControlRect, __isRecording, EditorGUILayoutEx.ANIMATION_STYLES.recordIcon, EditorStyles.toolbarButton); GUI.color = color; //restore color if (EditorGUI.EndChangeCheck()) { if (__isRecording) { if (!AnimationMode.InAnimationMode()) { List <EditorClipBinding> list = (clipBindingsSerialized.value as EditorClipBinding[]).ToList(); list.Add(__mecanimNodeClipBinding); __clipBindingsToBeAnimated = list.ToArray(); AnimationMode.StartAnimationMode(); Undo.postprocessModifications += PostprocessAnimationRecordingModifications; //calculate offset of boonRoot position before animation from boonRoot position at time=0s. AnimationModeUtility.SaveBindingsOffset(clipBindingsSerialized.value as EditorClipBinding[]); AnimationModeUtility.SaveBindingOffset(__mecanimNodeClipBinding); //calculate time in seconds from the current postion of time scrubber __timeCurrent = __timeNormalized * __spaceGameObjectAnimationClip.length; //apply clip animaiton at __timeCurrent AnimationModeUtility.SampleClipBindingAt(__clipBindingsToBeAnimated , __timeCurrent); LockRootGameObject(true); SceneView.RepaintAll(); } } else { //Remove Undo property modificaiton handlers Undo.postprocessModifications -= PostprocessAnimationRecordingModifications; AnimationMode.StopAnimationMode(); //reset gameobject with bones to state before animation AnimationModeUtility.ResetBindingsTransformPropertyModification(clipBindingsSerialized.value as EditorClipBinding[]); //reset Node.self gameObject AnimationModeUtility.ResetBindingTransformPropertyModification(__mecanimNodeClipBinding); LockRootGameObject(false); } } timeControlRect.xMin = 40f + 16f; timeControlRect.xMax = Screen.width - 68f; timeControlRect.yMin -= 2f; EditorGUI.BeginChangeCheck(); /// TIMELINE SLIDER /// __timeNormalized = EditorGUILayoutEx.CustomHSlider(timeControlRect, __timeNormalized, 0f, 1f, EditorGUILayoutEx.ANIMATION_STYLES.timeScrubber); if (EditorGUI.EndChangeCheck() || __timeNormalizedUpdate) { __timeCurrent = __timeNormalized * __spaceGameObjectAnimationClip.length; __timeNormalizedUpdate = false; if (!AnimationMode.InAnimationMode()) { AnimationMode.StartAnimationMode(); //calculate offset of boonRoot position before animation from boonRoot position at time=0s. AnimationModeUtility.SaveBindingsOffset(clipBindingsSerialized.value as EditorClipBinding[]); AnimationModeUtility.SaveBindingOffset(__mecanimNodeClipBinding); LockRootGameObject(true); } if (!__isRecording) { __isRecording = true; //add recording Undo events handlers Undo.postprocessModifications += PostprocessAnimationRecordingModifications; List <EditorClipBinding> list = (clipBindingsSerialized.value as EditorClipBinding[]).ToList(); list.Add(__mecanimNodeClipBinding); __clipBindingsToBeAnimated = list.ToArray(); } //moves clip to time: __timeCurrent AnimationModeUtility.SampleClipBindingAt(__clipBindingsToBeAnimated, __timeCurrent); } ///////////// ROTATION/SCALE KEYFRAMES ///////////////////////// Rect keyframesRect = GUILayoutUtility.GetRect(Screen.width - 16f, 16f); keyframesRect.xMax = timeControlRect.xMax + _keyframeMarker.image.width * 0.5f; keyframesRect.xMin = timeControlRect.xMin - _keyframeMarker.image.width * 0.5f; //Show rotation or scale keyframes if Rotation or Scale tools are selected if (Selection.activeGameObject != null) { if (Tools.current == Tool.Rotate) { EditorClipBinding clipBindingCurrent = (clipBindingsSerialized.value as EditorClipBinding[]).FirstOrDefault((itm) => itm.gameObject != null && itm.gameObject.transform.childCount > 0 && itm.gameObject.transform.GetChild(0).gameObject == Selection.activeGameObject); if (clipBindingCurrent != null && clipBindingCurrent.visible && clipBindingCurrent.clip != null) { EditorCurveBinding curveBinding = AnimationUtilityEx.EditorCurveBinding_RotX; curveBinding.path = AnimationUtility.CalculateTransformPath(clipBindingCurrent.gameObject.transform.GetChild(0), clipBindingCurrent.gameObject.transform.root); keyframeTimeValues = AnimationUtilityEx.GetTimesNormalized(clipBindingCurrent.clip, curveBinding, __spaceGameObjectAnimationClip.length); } else { keyframeTimeValues = new float[0]; } } else if (Tools.current == Tool.Scale) { EditorClipBinding clipBindingCurrent = (clipBindingsSerialized.value as EditorClipBinding[]).FirstOrDefault((itm) => itm.gameObject != null && itm.gameObject.transform.childCount > 0 && itm.gameObject.transform.GetChild(0).gameObject == Selection.activeGameObject); if (clipBindingCurrent != null && clipBindingCurrent.visible && clipBindingCurrent.clip != null) { EditorCurveBinding curveBinding = AnimationUtilityEx.EditorCurveBinding_SclX; curveBinding.path = AnimationUtility.CalculateTransformPath(clipBindingCurrent.gameObject.transform.GetChild(0), clipBindingCurrent.gameObject.transform.root); keyframeTimeValues = AnimationUtilityEx.GetTimesNormalized(clipBindingCurrent.clip, curveBinding, __spaceGameObjectAnimationClip.length); } else { keyframeTimeValues = new float[0]; } } else { keyframeTimeValues = new float[0]; } } else { keyframeTimeValues = new float[0]; } keyframesDisplayNames = keyframeTimeValues.Select((itm) => { return(Decimal.Round(Convert.ToDecimal(itm * __spaceGameObjectAnimationClip.length), 2).ToString() + ".s"); }).ToArray(); keyframeTimeValuesSelected = new bool[keyframeTimeValues.Length]; //used for multiselection option not used here //create custom timeline showing rotation or scale keyframes EditorGUILayoutEx.CustomTimeLine(ref keyframesRect, _keyframeMarker, ref keyframeTimeValues, ref eventTimeValuesPrev, ref keyframesDisplayNames, ref keyframeTimeValuesSelected, -1f, null, onKeyframeDelete, null, onKeyframeEdit, null ); // DISPLAY TIME in [s] and in [%] EditorGUILayout.LabelField("Time: " + Decimal.Round(Convert.ToDecimal(__timeCurrent), 2).ToString() + "s (" + Mathf.FloorToInt(__timeNormalized * 100) + "%) Frame:" + Mathf.FloorToInt(__timeCurrent * __spaceGameObjectAnimationClip.frameRate).ToString()); /////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /// /// Draw red time scrubber line on top of Curve Editor /// ////////////////////////////////////////////////////////////// if (_curvesEditorShow) { Handles.color = Color.red; float leftrightMargin = 39f; // 40f; float effectiveWidth = curveEditorRect.width - 2 * leftrightMargin - curveEditorRect.xMin; float timeLineX = curveEditorRect.xMin + leftrightMargin + effectiveWidth * __timeNormalized; Handles.DrawLine(new Vector2(timeLineX, curveEditorRect.y), new Vector2(timeLineX, curveEditorRect.y + curveEditorRect.height)); } ////////// EVALUATE CURVES ////////// int variablesNum = variablesBindedToCurves.Length; for (int varriableCurrentinx = 0; varriableCurrentinx < variablesNum; varriableCurrentinx++) { try { variablesBindedToCurves [varriableCurrentinx].Value = curves [varriableCurrentinx].Evaluate(__timeNormalized); } catch (Exception ex) { variablesBindedToCurves [varriableCurrentinx].name = "Invalid UVariable" + ex.Message; } } } }
/// <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> /// Handles the GUI event. /// </summary> void OnGUI() { if (_keyframeMarker == null) _keyframeMarker = new GUIContent (EditorGUILayoutEx.ANIMATION_STYLES.pointIcon); if (!Application.isPlaying && __gameObjectClipList!=null) { _curvesEditorShow = EditorGUILayout.Foldout (_curvesEditorShow, "Curves"); //int indentLevel = 0; Rect curveEditorRect = new Rect (0, 0, 0, 0); int i = 0; if (_curvesEditorShow) { //This makes layout to work (Reserving space) curveEditorRect = GUILayoutUtility.GetRect (Screen.width - 16f, 200); /////// CURVE EDITOR //////// curveEditorRect.width = curveEditorRect.width - 32f; curveEditorRect.x = 16f; if (curveEditor == null) { CurveWrapperW[] curveWrappers; int numCurves = curves.Length; curveWrappers = new CurveWrapperW[numCurves]; CurveWrapperW curveWrapperNew; for (i=0; i<numCurves; i++) { curveWrapperNew = new CurveWrapperW (); curveWrapperNew.curve = curves [i]; curveWrapperNew.color = curveColors [i]; curveWrappers [i] = curveWrapperNew; } curveEditor = new CurveEditorW (curveEditorRect, curveWrappers, false); curveEditor.FrameSelected (true, true); curveEditor.scaleWithWindow = true; curveEditor.hSlider = false; curveEditor.hRangeMin = 0f; curveEditor.hRangeMax = 1f; curveEditor.hRangeLocked = true; curveEditor.onSelect += onCurveSelect; } else { curveEditor.rect = curveEditorRect; curveEditor.FrameSelected (false, false); } curveEditor.DoEditor (); /////////////////////////////////////////////////////////////////////////////// ///////////// ADD/REMOVE CURVE BINDED TO OBJECT PROP OR GLOBAL VARIABLE ///////////// /// // EditorGUILayout.BeginHorizontal (); //if curve is selected display curve properties if (_curveIndexSelected > -1 && _curveIndexSelected < variablesBindedToCurves.Length) { UnityVariable variableSelected = variablesBindedToCurves [_curveIndexSelected]; try { bindingCurvesGUIContent.text = variableSelected.instanceBinded.name + "." + variableSelected.memberPath; EditorGUILayout.LabelField (bindingCurvesGUIContent, new GUILayoutOption[]{}); EditorGUI.BeginChangeCheck (); Color colorNew = EditorGUILayout.ColorField (curveColors [_curveIndexSelected]); if (EditorGUI.EndChangeCheck ()) { curveEditor.animationCurves [_curveIndexSelected].color = colorNew; curveColors [_curveIndexSelected] = colorNew; curvesColorsSerialized.ValueChanged (); curvesColorsSerialized.ApplyModifiedValue (); } } catch (MissingReferenceException ex) { bindingCurvesGUIContent.text = "Invalid UVariable " + ex.Message; } } else { bindingCurvesGUIContent.text = "Curve binding:"; List<UnityVariable> blackboardLocalList = (MecanimNodeEditorWindow.__serializedNode.target.blackboard as BlackboardCustom).GetVariableBy (typeof(float)); List<GUIContent> displayOptionsList = blackboardLocalList.Select ((item) => new GUIContent ("Local/" + item.name)).ToList (); __variableSelected = EditorGUILayoutEx.UnityVariablePopup (bindingCurvesGUIContent, __variableSelected, typeof(float), displayOptionsList, blackboardLocalList); _colorSelected = EditorGUILayout.ColorField (_colorSelected); } /////////////// ADD CURVE(+) ///////// if (GUILayout.Button ("Add") && __variableSelected != null) { List<UnityVariable> vList = variablesBindedToCurves.ToList (); vList.Add (__variableSelected); variablesBindedToCurvesSerialized.value = variablesBindedToCurves = vList.ToArray (); variablesBindedToCurvesSerialized.ValueChanged (); //variablesBindedToCurvesSerialized.ApplyModifiedValue (); List<Color> cList = curveColors.ToList (); _colorSelected.a = 1; cList.Add (_colorSelected); curvesColorsSerialized.value = curveColors = cList.ToArray (); curvesColorsSerialized.ValueChanged (); //curvesColorsSerialized.ApplyModifiedValue (); AnimationCurve curveAnimationNew; List<AnimationCurve> crList = curves.ToList (); curveAnimationNew = new AnimationCurve (new Keyframe[] { new Keyframe (0f, (float)__variableSelected.Value), new Keyframe (1f, 1f) }); //TODO add from preset crList.Add (curveAnimationNew); curvesSerialized.value = curves = crList.ToArray (); curvesSerialized.ValueChanged (); //curvesColorsSerialized.ApplyModifiedValue (); ///add curve wrapped to CurveEditor CurveWrapperW curveWrapperW = new CurveWrapperW (); curveWrapperW.color = _colorSelected; curveWrapperW.curve = curveAnimationNew; curveEditor.AddCurve (curveWrapperW); curveEditor.FrameSelected (true, true); __serializedNode.Update (); __serializedNode.ApplyModifiedProperties (); __variableSelected = null; } ///////////// DELETE CURVE //////////// if (GUILayout.Button ("Del") || Event.current.keyCode == KeyCode.Delete) { curveEditor.RemoveCurveAt (_curveIndexSelected); List<UnityVariable> vList = variablesBindedToCurves.ToList (); vList.RemoveAt (_curveIndexSelected); variablesBindedToCurvesSerialized.value = variablesBindedToCurves = vList.ToArray (); variablesBindedToCurvesSerialized.ValueChanged (); List<Color> cList = curveColors.ToList (); cList.RemoveAt (_curveIndexSelected); curvesColorsSerialized.value = curveColors = cList.ToArray (); curvesColorsSerialized.ValueChanged (); List<AnimationCurve> crList = curves.ToList (); crList.RemoveAt (_curveIndexSelected); curvesSerialized.value = curves = crList.ToArray (); curvesSerialized.ValueChanged (); _curveIndexSelected = -1; __variableSelected = null; __serializedNode.ApplyModifiedProperties (); } EditorGUILayout.EndHorizontal (); } else {//NOT CURVE EDITOR ///////////// GAMEOBJECT - CLIP BINDINGS ////////// __gameObjectClipList.DoLayoutList (); ////////////////////////////////////////////// } EditorGUILayout.Space (); __mecanimNodeClipBinding.clip = __spaceGameObjectAnimationClip; ///////////// TIME CONTROL OF ANIMATION (SLIDER) ///////// Rect timeControlRect = GUILayoutUtility.GetRect (Screen.width, 26f); timeControlRect.xMax = 32f; ///////////// PLAY ANIMATION TOGGLE ///////// __isPlaying = GUI.Toggle (timeControlRect, __isPlaying, !__isPlaying ? EditorGUILayoutEx.ANIMATION_STYLES.playIcon : EditorGUILayoutEx.ANIMATION_STYLES.pauseIcon, EditorGUILayoutEx.ANIMATION_STYLES.playButton); if (__isPlaying) { } else { } timeControlRect.xMin = timeControlRect.xMax + 1f; timeControlRect.xMax = timeControlRect.xMin + 21f; timeControlRect.yMin += 2f; EditorGUI.BeginChangeCheck (); Color color = GUI.color;//save color if (AnimationMode.InAnimationMode ()) GUI.color = AnimationMode.animatedPropertyColor;//change color of record button to red ///////////// RECORD ANIMATION TOGGLE ///////// __isRecording = GUI.Toggle (timeControlRect, __isRecording, EditorGUILayoutEx.ANIMATION_STYLES.recordIcon, EditorStyles.toolbarButton); GUI.color = color;//restore color if (EditorGUI.EndChangeCheck ()) if (__isRecording) { if (!AnimationMode.InAnimationMode ()) { List<EditorClipBinding> list = (clipBindingsSerialized.value as EditorClipBinding[]).ToList (); list.Add (__mecanimNodeClipBinding); __clipBindingsToBeAnimated = list.ToArray (); AnimationMode.StartAnimationMode (); Undo.postprocessModifications += PostprocessAnimationRecordingModifications; //calculate offset of boonRoot position before animation from boonRoot position at time=0s. AnimationModeUtility.SaveBindingsOffset (clipBindingsSerialized.value as EditorClipBinding[]); AnimationModeUtility.SaveBindingOffset (__mecanimNodeClipBinding); //calculate time in seconds from the current postion of time scrubber __timeCurrent = __timeNormalized * __spaceGameObjectAnimationClip.length; //apply clip animaiton at __timeCurrent AnimationModeUtility.SampleClipBindingAt (__clipBindingsToBeAnimated , __timeCurrent); LockRootGameObject (true); SceneView.RepaintAll (); } } else { //Remove Undo property modificaiton handlers Undo.postprocessModifications -= PostprocessAnimationRecordingModifications; AnimationMode.StopAnimationMode (); //reset gameobject with bones to state before animation AnimationModeUtility.ResetBindingsTransformPropertyModification (clipBindingsSerialized.value as EditorClipBinding[]); //reset Node.self gameObject AnimationModeUtility.ResetBindingTransformPropertyModification (__mecanimNodeClipBinding); LockRootGameObject (false); } timeControlRect.xMin = 40f + 16f; timeControlRect.xMax = Screen.width - 68f; timeControlRect.yMin -= 2f; EditorGUI.BeginChangeCheck (); /// TIMELINE SLIDER /// __timeNormalized = EditorGUILayoutEx.CustomHSlider (timeControlRect, __timeNormalized, 0f, 1f, EditorGUILayoutEx.ANIMATION_STYLES.timeScrubber); if (EditorGUI.EndChangeCheck () || __timeNormalizedUpdate) { __timeCurrent = __timeNormalized * __spaceGameObjectAnimationClip.length; __timeNormalizedUpdate = false; if (!AnimationMode.InAnimationMode ()) { AnimationMode.StartAnimationMode (); //calculate offset of boonRoot position before animation from boonRoot position at time=0s. AnimationModeUtility.SaveBindingsOffset (clipBindingsSerialized.value as EditorClipBinding[]); AnimationModeUtility.SaveBindingOffset (__mecanimNodeClipBinding); LockRootGameObject (true); } if (!__isRecording) { __isRecording = true; //add recording Undo events handlers Undo.postprocessModifications += PostprocessAnimationRecordingModifications; List<EditorClipBinding> list = (clipBindingsSerialized.value as EditorClipBinding[]).ToList (); list.Add (__mecanimNodeClipBinding); __clipBindingsToBeAnimated = list.ToArray (); } //moves clip to time: __timeCurrent AnimationModeUtility.SampleClipBindingAt (__clipBindingsToBeAnimated, __timeCurrent); } ///////////// ROTATION/SCALE KEYFRAMES ///////////////////////// Rect keyframesRect = GUILayoutUtility.GetRect (Screen.width - 16f, 16f); keyframesRect.xMax = timeControlRect.xMax+_keyframeMarker.image.width*0.5f; keyframesRect.xMin = timeControlRect.xMin-_keyframeMarker.image.width*0.5f; //Show rotation or scale keyframes if Rotation or Scale tools are selected if (Selection.activeGameObject != null) { if (Tools.current == Tool.Rotate) { EditorClipBinding clipBindingCurrent = (clipBindingsSerialized.value as EditorClipBinding[]).FirstOrDefault ((itm) => itm.gameObject != null && itm.gameObject.transform.childCount > 0 && itm.gameObject.transform.GetChild (0).gameObject == Selection.activeGameObject); if (clipBindingCurrent != null && clipBindingCurrent.visible && clipBindingCurrent.clip != null) { EditorCurveBinding curveBinding = AnimationUtilityEx.EditorCurveBinding_RotX; curveBinding.path = AnimationUtility.CalculateTransformPath (clipBindingCurrent.gameObject.transform.GetChild (0), clipBindingCurrent.gameObject.transform.root); keyframeTimeValues = AnimationUtilityEx.GetTimes (clipBindingCurrent.clip, curveBinding, __spaceGameObjectAnimationClip.length); }else keyframeTimeValues = new float[0]; } else if (Tools.current == Tool.Scale) { EditorClipBinding clipBindingCurrent = (clipBindingsSerialized.value as EditorClipBinding[]).FirstOrDefault ((itm) => itm.gameObject != null && itm.gameObject.transform.childCount > 0 && itm.gameObject.transform.GetChild (0).gameObject == Selection.activeGameObject); if (clipBindingCurrent != null && clipBindingCurrent.visible && clipBindingCurrent.clip != null) { EditorCurveBinding curveBinding = AnimationUtilityEx.EditorCurveBinding_SclX; curveBinding.path = AnimationUtility.CalculateTransformPath (clipBindingCurrent.gameObject.transform.GetChild (0), clipBindingCurrent.gameObject.transform.root); keyframeTimeValues = AnimationUtilityEx.GetTimes (clipBindingCurrent.clip, curveBinding, __spaceGameObjectAnimationClip.length); }else keyframeTimeValues = new float[0]; } else keyframeTimeValues = new float[0]; } else { keyframeTimeValues = new float[0]; } keyframesDisplayNames = keyframeTimeValues.Select ((itm) => { return Decimal.Round (Convert.ToDecimal (itm * __spaceGameObjectAnimationClip.length), 2).ToString () + ".s"; }).ToArray (); keyframeTimeValuesSelected = new bool[keyframeTimeValues.Length];//used for multiselection option not used here //create custom timeline showing rotation or scale keyframes EditorGUILayoutEx.CustomTimeLine (ref keyframesRect, _keyframeMarker, ref keyframeTimeValues, ref eventTimeValuesPrev, ref keyframesDisplayNames, ref keyframeTimeValuesSelected, -1f, null, onKeyframeDelete, null, onKeyframeEdit, null ); // DISPLAY TIME in [s] and in [%] EditorGUILayout.LabelField ("Time: " + Decimal.Round (Convert.ToDecimal (__timeCurrent), 2).ToString () + "s (" + Mathf.FloorToInt (__timeNormalized * 100) + "%) Frame:" + Mathf.FloorToInt (__timeCurrent * __spaceGameObjectAnimationClip.frameRate).ToString ()); /////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /// /// Draw red time scrubber line on top of Curve Editor /// ////////////////////////////////////////////////////////////// if (_curvesEditorShow) { Handles.color = Color.red; float leftrightMargin = 39f;// 40f; float effectiveWidth = curveEditorRect.width - 2 * leftrightMargin - curveEditorRect.xMin; float timeLineX = curveEditorRect.xMin + leftrightMargin + effectiveWidth * __timeNormalized; Handles.DrawLine (new Vector2 (timeLineX, curveEditorRect.y), new Vector2 (timeLineX, curveEditorRect.y + curveEditorRect.height)); } ////////// EVALUATE CURVES ////////// int variablesNum = variablesBindedToCurves.Length; for (int varriableCurrentinx=0; varriableCurrentinx<variablesNum; varriableCurrentinx++) { try { variablesBindedToCurves [varriableCurrentinx].Value = curves [varriableCurrentinx].Evaluate (__timeNormalized); } catch (Exception ex) { variablesBindedToCurves [varriableCurrentinx].name = "Invalid UVariable" + ex.Message; } } } }
/// <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> /// 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(); } } }
// public override void ResetStatus () // { // Debug.Log (selectedAnimaStateInfo.label.text + ">ResetStatus"); // base.ResetStatus (); // } public override void Reset() { animator = self.GetComponent<Animator> (); transitionDuration = 0f; clipBindings = new EditorClipBinding[0]; curvesColors = new Color[0]; curves = new AnimationCurve[0]; variablesBindedToCurves = new UnityVariable[0]; animatorStateSelected = (AnimatorState)ScriptableObject.CreateInstance<AnimatorState> (); blendX = UnityVariable.CreateInstanceOf (typeof(float)); blendY = UnityVariable.CreateInstanceOf (typeof(float)); motionOverride = UnityVariable.CreateInstanceOf (typeof(AnimationClip)); range = (ws.winx.unity.attributes.MinMaxRangeSO)ScriptableObject.CreateInstance<ws.winx.unity.attributes.MinMaxRangeSO> (); Array.ForEach (this.children, (itm) => { //remove localy from node parent this.Remove (itm); //remove from internal behaviour tree this.tree.RemoveNode (itm, false); }); }
public static SerializedProperty SerializeObject(object obj) { //ws.winx.csharp.CSharpCodeCompilerOriginal compOrig = new ws.winx.csharp.CSharpCodeCompilerOriginal (); ws.winx.csharp.CSharpCodeCompiler compOrig = new ws.winx.csharp.CSharpCodeCompiler(); ws.winx.csharp.CSharpCodeCompiler.unixMcsCommand = "/Applications/Unity/MonoDevelop.app/Contents/Frameworks/Mono.framework/Versions/Current/bin/gmcs"; object value = obj; if (obj is UnityVariable) { UnityVariable var = obj as UnityVariable; value = var.Value; } Type ValueType = obj is UnityVariable? (obj as UnityVariable).ValueType : obj.GetType(); //System.CodeDom.Compiler.CodeDomProvider provider = new CodeDomProvider (); CompilerParameters compilerParams = new System.CodeDom.Compiler.CompilerParameters(); compilerParams.GenerateInMemory = true; var assembyExcuting = Assembly.GetExecutingAssembly(); string assemblyLocationUnity = Assembly.GetAssembly(typeof(ScriptableObject)).Location; string usingString = "using UnityEngine;"; if (!(ValueType.IsPrimitive || ValueType == typeof(string))) { string assemblyLocationVarable = Assembly.GetAssembly(ValueType).Location; compilerParams.ReferencedAssemblies.Add(assemblyLocationVarable); if (String.Compare(assemblyLocationUnity, assemblyLocationVarable) != 0) { usingString += "using " + ValueType.Namespace + ";"; } } compilerParams.ReferencedAssemblies.Add(assemblyLocationUnity); compilerParams.ReferencedAssemblies.Add(assembyExcuting.Location); // Create class with one property value of type same as type of the object we want to serialize String sourceCodeString = String.Format( " {0}" + "public class ScriptableObjectTemplate:ScriptableObject {{ public {1} value;}}" , usingString, ValueType.ToCSharpString()); Type[] genericTypes = null; if (ValueType.IsGenericType && ValueType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { genericTypes = ValueType.GetGenericArguments(); genericTypes[0] = typeof(List <>).MakeGenericType(new Type[] { genericTypes[0] }); genericTypes[1] = typeof(List <>).MakeGenericType(new Type[] { genericTypes[1] }); sourceCodeString = String.Format( " {0}" + "public class ScriptableObjectTemplate:ScriptableObject {{ " + "public {1} keys;" + "public {2} values;" + "}}" , usingString, genericTypes[0].ToCSharpString(), genericTypes[1].ToCSharpString() ); } var res = compOrig.CompileAssemblyFromSource( compilerParams, sourceCodeString) ; if (res.Errors.Count > 0) { foreach (CompilerError CompErr in res.Errors) { Debug.LogError( "Line number " + CompErr.Line + ", Error Number: " + CompErr.ErrorNumber + ", '" + CompErr.ErrorText + ";" ); } return(null); } else { var type = res.CompiledAssembly.GetType("ScriptableObjectTemplate"); ScriptableObject st = ScriptableObject.CreateInstance(type); if (ValueType.IsGenericType && ValueType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { IDictionary valueDict = value as IDictionary; IList keysList = Activator.CreateInstance(genericTypes[0]) as IList; IList valuesList = Activator.CreateInstance(genericTypes[1]) as IList; IEnumerator eKeys = valueDict.Keys.GetEnumerator(); IEnumerator eValues = valueDict.Values.GetEnumerator(); while (eKeys.MoveNext()) { keysList.Add(eKeys.Current); eValues.MoveNext(); valuesList.Add(eValues.Current); } st.GetType().GetField("keys").SetValue(st, keysList); st.GetType().GetField("values").SetValue(st, valuesList); } else { type.GetField("value").SetValue(st, value); } SerializedObject seralizedObject = new SerializedObject(st); SerializedProperty serializedProp = seralizedObject.FindProperty("value"); if (serializedProp == null) { serializedProp = seralizedObject.FindProperty("values"); } if (serializedProp == null) { Debug.LogError("Can't serialize " + obj); } return(serializedProp); } }
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(); }