/// <summary> /// Ons the keyframe delete. /// </summary> /// <param name="args">Arguments.</param> static void onKeyframeDelete(TimeLineArgs <float> args) { EditorClipBinding clipBindingCurrent = (clipBindingsSerialized.value as EditorClipBinding[]).FirstOrDefault((itm) => itm.gameObject != null && itm.gameObject.transform.childCount > 0 && itm.gameObject.transform.GetChild(0).gameObject == Selection.activeGameObject); //AnimationUtilityEx.RemoveKeyframeFrom (clipBindingCurrent.clip, args.selectedIndex); }
public override void OnInspectorGUI() { //serializedObject.Update (); sequence = sequenceSerialziedProperty.objectReferenceValue as Sequence; EditorGUI.BeginChangeCheck(); if (sequence != null) { wrapSerializedProperty.enumValueIndex = (int)sequence.wrap; EditorGUILayout.PropertyField(wrapSerializedProperty, wrapCurrentGUIContent); sequence.wrap = (Sequence.SequenceWrap)wrapSerializedProperty.enumValueIndex; } EditorGUILayout.PropertyField(playOnStartSerializedProperty, playOnStartGUIContent); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(sequenceSerialziedProperty, sequenceGUIContent); if (GUILayout.Button(cloneSequenceGUIContent)) { if (sequence != null) { Sequence sequenceNew = ScriptableObject.CreateInstance <Sequence>(); EditorUtilityEx.CreateAssetFromInstance(sequenceNew); foreach (SequenceChannel channel in sequence.channels) { SequenceChannel channelClone = UnityEngine.Object.Instantiate <SequenceChannel>(channel); channelClone.nodes.Clear(); sequenceNew.channels.Add(channelClone); channelClone.sequence = sequenceNew; AssetDatabase.AddObjectToAsset(channelClone, sequenceNew); foreach (SequenceNode node in channel.nodes) { SequenceNode nodeClone = UnityEngine.Object.Instantiate <SequenceNode>(node); nodeClone.channel = channelClone; channelClone.nodes.Add(nodeClone); AssetDatabase.AddObjectToAsset(nodeClone, channelClone); EditorClipBinding clipBindingClone = UnityEngine.Object.Instantiate <EditorClipBinding>(node.clipBinding); nodeClone.clipBinding = clipBindingClone; AssetDatabase.AddObjectToAsset(clipBindingClone, nodeClone); } } } } EditorGUILayout.EndHorizontal(); if (sequence != null) { timeCurrentSerializedProperty.floatValue = (float)sequence.timeCurrent; timeCurrentSerializedProperty.serializedObject.ApplyModifiedProperties(); EditorGUILayout.Slider(timeCurrentSerializedProperty, (float)sequence.timeStart, (float)sequence.timeEnd); sequence.timeCurrent = timeCurrentSerializedProperty.floatValue; EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Goto")) { sequence.GoTo(timeCurrentSerializedProperty.floatValue); } if (GUILayout.Button(!Application.isPlaying ? (sequence.isPlaying ? "Pause" : "Play Forward") : "Play Forward")) { if (Application.isPlaying) { sequence.Play(sequence.timeCurrent); } else { SequenceEditorWindow.Play(); } } if (GUILayout.Button("Play Backward")) { if (Application.isPlaying) { sequence.Play(sequence.timeCurrent, false); } else { SequenceEditorWindow.Play(false); } } if (GUILayout.Button("Stop")) { if (Application.isPlaying) { sequence.Stop(); } else { SequenceEditorWindow.Stop(); } } if (Application.isPlaying) { if (GUILayout.Button("Pause")) { Debug.LogWarning("Not yet tested, not finished"); sequence.Pause(); } } if (Application.isPlaying) { if (GUILayout.Button("UnPause")) { Debug.LogWarning("Not yet tested, not finished"); sequence.UnPause(); } } if (!Application.isPlaying) { if (GUILayout.Button("Open Editor")) { SequenceEditorWindow.ShowWindow(); } } EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); SequenceEditorWindow.window.Repaint(); } //EditorUtilityEx.GetDrawer(typeof(UnityEngine.Events.UnityEventBase)). ///// DRAW SELECTED NODE (inside SequenceEditor) //////// SequenceNode selectedNode = sequence.nodeSelected; if (selectedNode != null) { if (selectedNode != selectedNodePrev) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Selected Node"); EditorGUILayout.Space(); nodeEditor = Editor.CreateEditor(selectedNode, typeof(SequenceNodeEditor)) as SequenceNodeEditor; EditorGUILayout.Space(); } nodeEditor.OnInspectorGUI(); } else { EditorGUILayout.LabelField("No Node selected"); } selectedNodePrev = selectedNode; } }
/// <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.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> /// Handles draw list element. /// </summary> /// <param name="rect">Rect.</param> /// <param name="index">Index.</param> /// <param name="isActive">If set to <c>true</c> is active.</param> /// <param name="isFocused">If set to <c>true</c> is focused.</param> private static void onDrawElement(Rect rect, int index, bool isActive, bool isFocused) { EditorClipBinding clipBindingCurrent = __gameObjectClipList.list [index] as EditorClipBinding; if (clipBindingCurrent == null) { return; } float width = rect.xMax; rect.xMax = 200f; ///////////// ADD GAMEOBJECT TO CLIPBINDING ///////// EditorGUI.BeginChangeCheck(); GameObject gameObjectHolderBinded = EditorGUI.ObjectField(rect, clipBindingCurrent.gameObject, typeof(GameObject), true) as GameObject; if (EditorGUI.EndChangeCheck() && gameObjectHolderBinded != null && gameObjectHolderBinded.transform.childCount == 1) { clipBindingCurrent.gameObject = gameObjectHolderBinded; clipBindingCurrent.positionOffset = Quaternion.Inverse(__spaceGameObject.transform.rotation) * (clipBindingCurrent.gameObject.transform.position - __spaceGameObject.transform.position); clipBindingCurrent.rotationOffset = Quaternion.Inverse(__spaceGameObject.transform.rotation) * gameObjectHolderBinded.transform.rotation; } rect.xMin = rect.xMax + 2; rect.xMax = width - 100f; ///////////// ADD ANIMATION CLIP TO CLIPBINDING ///////// clipBindingCurrent.clip = EditorGUI.ObjectField(rect, clipBindingCurrent.clip, typeof(AnimationClip), true) as AnimationClip; if (clipBindingCurrent.clip == null) { rect.xMin = rect.xMax + 2; rect.xMax = rect.xMin + 30f; if (GUI.Button(rect, "New Clip")) { string path = EditorUtility.SaveFilePanel( "Create New Clip", "Assets", "", "anim"); if (!String.IsNullOrEmpty(path)) { AnimationClip clip = new AnimationClip(); //UnityEditor.Animations.AnimatorController.AllocateAnimatorClip (); clip.name = Path.GetFileNameWithoutExtension(path); AssetDatabase.CreateAsset(clip, AssetDatabaseUtility.AbsoluteUrlToAssets(path)); AssetDatabase.SaveAssets(); clipBindingCurrent.clip = clip; clipBindingCurrent.clip.frameRate = __spaceGameObjectAnimationClip.frameRate; } } } ///////////// COLOR PATH CLIPBINDING ///////// rect.xMin = rect.xMax + 2f; rect.xMax = rect.xMin + 30f; clipBindingCurrent.color = EditorGUI.ColorField(rect, clipBindingCurrent.color); ///////////// CLIPBINDING PATH SHOW/HIDE ///////// rect.xMin = rect.xMax + 2f; rect.xMax = width; clipBindingCurrent.visible = EditorGUI.Toggle(rect, clipBindingCurrent.visible); }
/// <summary> /// Handles the scene GUI event. /// </summary> /// <param name="sceneView">Scene view.</param> private static void OnSceneGUI(SceneView sceneView) { if (clipBindingsSerialized.value == null) { return; } EditorClipBinding[] clipBindings = clipBindingsSerialized.value as EditorClipBinding[]; int bindingsLength = clipBindings.Length; Color clr = Color.red; Vector3[] positionsInKeyframe = null; AnimationClip clip = null; EditorClipBinding clipBindingCurrent = null; long indexListAndindexFramePacked = 0; Transform transformRoot = null; Transform transformFirstChild = null; bool gameObjectCharacterSelected = false; if (Selection.activeGameObject != null) { if (Tools.current == Tool.Move) { if (Selection.activeGameObject == __spaceGameObject) { gameObjectCharacterSelected = true; } else { clipBindingCurrent = clipBindings.FirstOrDefault((itm) => itm.gameObject == Selection.activeGameObject); // && clipBindingCurrent.gameObject.transform.position!=Tools.handlePosition if (clipBindingCurrent != null) { //clipBindingCurrent.gameObject.position has changed so recalcualte position offset clipBindingCurrent.positionOffset = Quaternion.Inverse(__spaceGameObject.transform.rotation) * (clipBindingCurrent.gameObject.transform.position - __spaceGameObject.transform.position); } } } else if (Tools.current == Tool.Rotate) { if (Selection.activeGameObject == __spaceGameObject) { gameObjectCharacterSelected = true; } else { clipBindingCurrent = clipBindings.FirstOrDefault((itm) => itm.gameObject == Selection.activeGameObject); // && clipBindingCurrent.gameObject.transform.position!=Tools.handleRotation if (clipBindingCurrent != null) { //clipBindingCurrent.gameObject.rotation has changed so recalcualte rotation offset clipBindingCurrent.rotationOffset = Quaternion.Inverse(__spaceGameObject.transform.rotation) * clipBindingCurrent.gameObject.transform.rotation; } } } } for (int i = 0; i < bindingsLength; i++) { clipBindingCurrent = clipBindings [i]; if (clipBindingCurrent.visible) { clip = clipBindingCurrent.clip; if (clip != null && clipBindingCurrent.gameObject != null && clipBindingCurrent.gameObject.transform.childCount > 0 && (transformFirstChild = clipBindingCurrent.gameObject.transform.GetChild(0)) != null) { if (gameObjectCharacterSelected) //=> move and/or rotate clip binding's gameobjects { GameObject gameObjectBinded = clipBindingCurrent.gameObject; gameObjectBinded.transform.rotation = __spaceGameObject.transform.rotation * clipBindingCurrent.rotationOffset; gameObjectBinded.transform.position = __spaceGameObject.transform.position + __spaceGameObject.transform.rotation * clipBindingCurrent.positionOffset; } transformRoot = clipBindingCurrent.gameObject.transform; positionsInKeyframe = AnimationUtilityEx.GetPositions(clip, AnimationUtility.CalculateTransformPath(transformFirstChild, transformRoot), transformRoot); if (positionsInKeyframe != null) { for (int j = 0; j < positionsInKeyframe.Length; j++) { indexListAndindexFramePacked = i; //put index of clipBinding in list/array indexListAndindexFramePacked = indexListAndindexFramePacked << 32 | (uint)j; //pack together with keyframe index //actualy this is static handle HandlesEx.DragHandle(positionsInKeyframe [j], 0.1f, Handles.SphereCap, Color.red, "(" + j + ")" + " " + Decimal.Round(Convert.ToDecimal(AnimationUtilityEx.GetTimeAt(clip, j, AnimationUtilityEx.EditorCurveBinding_PosX)), 2).ToString(), indexListAndindexFramePacked, onDragHandleEvent, new GUIContent[] { new GUIContent("Delete") }, new long[] { j }, null); } //save color clr = Handles.color; clipBindingCurrent.color.a = 1; Handles.color = clipBindingCurrent.color; Handles.DrawPolyLine(positionsInKeyframe); //restore color Handles.color = clr; } } } } //Debug.Log ("hot"+GUIUtility.hotControl); SceneView.RepaintAll(); }