public override void OnInspectorGUI() { serializedObject.Update (); EditorGUILayout.PropertyField (OnStartSerializedProperty, new GUIContent("OnStart")); EditorGUILayout.PropertyField (OnEndSerializedProperty, new GUIContent("OnEnd")); EditorGUILayout.PropertyField (wrapSerializedProperty, new GUIContent("Wrap Mode")); EditorGUILayout.PropertyField (playOnStartSerializedProperty, new GUIContent("Play On Start")); SequenceNode selectedNode=selectedNodeSerializedProperty.objectReferenceValue as SequenceNode; serializedObject.ApplyModifiedProperties (); Sequence sequence = target as Sequence; EditorGUILayout.BeginHorizontal (); if (GUILayout.Button ("Play")) { sequence.PlayAt(); } if (GUILayout.Button ("Stop Forward")) { sequence.Stop(true); } if (GUILayout.Button ("Stop Reset")) { //sequence.Stop(false); Debug.Log("Not yet tested, not finished"); } if (GUILayout.Button ("Pause")) { //sequence.Pause(); Debug.Log("Not yet tested, not finished"); } if (GUILayout.Button ("UnPause")) { Debug.Log("Not yet tested, not finished"); //sequence.UnPause(); } if (GUILayout.Button ("Restart")) { //sequence.Restart(); Debug.Log("Not yet tested, not finished"); } if (GUILayout.Button ("Open Editor")) { SequenceEditorWindow.ShowWindow(); } EditorGUILayout.EndHorizontal (); if (selectedNode != null){ if(selectedNode!=selectedNodePrev) nodeEditor=Editor.CreateEditor (selectedNode, typeof(SequenceNodeEditor)) as SequenceNodeEditor; selectedNodePrev=selectedNode; nodeEditor.OnInspectorGUI(); } }
/// <summary> /// Dos the node. /// </summary> /// <param name="node">Node.</param> /// <param name="rect">Rect.</param> /// <param name="channelOrd">Channel ord.</param> private static void DoNode(SequenceNode node, Rect rect, int channelOrd) { EditorGUIUtility.AddCursorRect (new Rect (__timeAreaW.TimeToPixel (node.startTime, rect) - 5, TIME_LABEL_HEIGHT + EVENT_PAD_HEIGHT + channelOrd * NODE_RECT_HEIGHT, 10, NODE_RECT_HEIGHT), MouseCursor.ResizeHorizontal); EditorGUIUtility.AddCursorRect (new Rect (__timeAreaW.TimeToPixel (node.startTime + node.duration, rect) - 5, TIME_LABEL_HEIGHT + channelOrd * NODE_RECT_HEIGHT, 10, NODE_RECT_HEIGHT), MouseCursor.ResizeHorizontal); float startTimePos = __timeAreaW.TimeToPixel (node.startTime + node.transition, rect); float endTimePos = __timeAreaW.TimeToPixel (node.startTime + node.duration, rect); float startTransitionTimePos = 0f; SequenceNode nodePrev = null; //if there is next node with transition // if (node.index + 1< node.channel.nodes.Count && (nodePrev = node.channel.nodes [node.index - 1]).transition > 0) { // // startTimePos = __timeAreaW.TimeToPixel (node.startTime + nodePrev.transition, rect); // // } //Draw Transtion rect if (node.transition > 0) { Color colorSave = GUI.color; GUI.color = Color.red; startTransitionTimePos = __timeAreaW.TimeToPixel (node.startTime, rect); Rect transitionRect = new Rect (startTransitionTimePos, TIME_LABEL_HEIGHT + EVENT_PAD_HEIGHT + channelOrd * NODE_RECT_HEIGHT, startTimePos - startTransitionTimePos, NODE_RECT_HEIGHT); GUI.Box (transitionRect, "", "TL LogicBar 0"); GUI.color = colorSave; } Rect nodeRect = new Rect (startTimePos, TIME_LABEL_HEIGHT + EVENT_PAD_HEIGHT + channelOrd * NODE_RECT_HEIGHT, endTimePos - startTimePos, NODE_RECT_HEIGHT); GUI.Box (nodeRect, "", "TL LogicBar 0"); nodeRect.xMin += 5; nodeRect.xMax -= 5; EditorGUIUtility.AddCursorRect (nodeRect, MouseCursor.Pan); GUIStyle style = new GUIStyle ("Label"); style.fontSize = (__nodeSelected == node ? 12 : style.fontSize); style.fontStyle = (__nodeSelected == node ? FontStyle.Bold : FontStyle.Normal); Color color = style.normal.textColor; color.a = (__nodeSelected == node ? 1.0f : 0.7f); style.normal.textColor = color; //calc draw name of the node __nodeLabelGUIContent.text = node.name; Vector3 size = style.CalcSize (__nodeLabelGUIContent); int labelLength = node.name.Length; //if labelWidth is greater then node box rect => remove chars while (nodeRect.width < size.x && labelLength>0) { __nodeLabelGUIContent.text = node.name.Substring (0, labelLength); size = style.CalcSize (__nodeLabelGUIContent); labelLength--; } if (labelLength > 0) { Rect rect1 = new Rect (nodeRect.x + nodeRect.width * 0.5f - size.x * 0.5f, nodeRect.y + nodeRect.height * 0.5f - size.y * 0.5f, size.x, size.y); GUI.Label (rect1, __nodeLabelGUIContent, style); } }
/// <summary> /// Sequences the drop source event handler. /// </summary> /// <param name="area">Area.</param> /// <param name="channel">Channel.</param> public void sequenceDropSourceEventHandler(Rect area, int channel) { if (__sequence.isPlaying || __sequence.isRecording) return; Event evt = Event.current; switch (evt.type) { case EventType.DragUpdated: case EventType.DragPerform: if (!area.Contains (evt.mousePosition)) return; DragAndDrop.visualMode = DragAndDropVisualMode.Copy; Type draggedType; if (evt.type == EventType.DragPerform) { DragAndDrop.AcceptDrag (); if (EditorApplication.isPlaying) { Debug.Log ("Can't add tween object in play mode. Stop the play mode and readd it."); } else { foreach (UnityEngine.Object dragged_object in DragAndDrop.objectReferences) { //Debug.Log ("Dropped object of type:" + dragged_object); //handle sound, video, animation clip draggedType = dragged_object.GetType (); if (draggedType == typeof(UnityEngine.AnimationClip) || draggedType == typeof(UnityEngine.AudioClip) || draggedType == typeof(UnityEngine.MovieTexture)) { Stop (); //allow only dropping multiply items of same type in same channel SequenceChannel sequenceChannel = null; if (channel < __sequence.channels.Count) { sequenceChannel = __sequence.channels [channel]; } else { sequenceChannel = (SequenceChannel)ScriptableObject.CreateInstance<SequenceChannel> (); if (draggedType == typeof(AnimationClip)) { //open Animation controller for the channel string path = EditorUtility.OpenFilePanel ( "Select AnimaitonController", "Assets", "controller"); if (String.IsNullOrEmpty (path)) continue; sequenceChannel.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath (AssetDatabaseUtility.AbsoluteUrlToAssets (path), typeof(RuntimeAnimatorController)) as RuntimeAnimatorController; sequenceChannel.name = "Animation"; } else if (draggedType == typeof(AudioClip)) { sequenceChannel.name = "Audio"; sequenceChannel.type = SequenceChannel.SequenceChannelType.Audio; } else if (draggedType == typeof(MovieTexture)) { sequenceChannel.name = "Video"; sequenceChannel.type = SequenceChannel.SequenceChannelType.Video; } sequenceChannel.sequence = __sequence; __sequence.channels.Add (sequenceChannel); } if (sequenceChannel.nodes.Count > 0) { if (sequenceChannel.nodes [0].source.GetType () != draggedType) { Debug.LogWarning ("You can have only same type nodes in same channel"); continue; } } //Vector2 //TODO current logic prevents overlapping on drop (might be ehnaced to allow transition overlap in Animation's node to some meassure) //and if they overlapp move start time to fit SequenceNode node = CreateNewSequenceNode (Event.current.mousePosition, dragged_object, channel); if (node != null) { sequenceChannel.nodes.Insert (node.index, node); int nodesCount = sequenceChannel.nodes.Count; //reindex nodes after insert for (int i=node.index+1; i<nodesCount; i++) sequenceChannel.nodes [i].index++; __sequence.timeCurrent = 0f; ResetChannelsTarget (); __needSave = true; } __nodeSelected = node; } } EditorUtility.SetDirty (__sequence); } } break; } }
/// <summary> /// Ons the sequence node stop. /// </summary> /// <param name="node">Node.</param> public static void onSequenceNodeStop(SequenceNode node) { }
/// <summary> /// Sequence's node click event handler. /// </summary> /// <param name="node">Node.</param> /// <param name="rect">Rect.</param> /// <param name="channelOrd">Channel ord.</param> private void sequenceNodeClickEventHandler(SequenceNode node, Rect rect, int channelOrd) { Event ev = Event.current; Rect clickRect; float startTime; switch (ev.rawType) { case EventType.MouseDown: clickRect = new Rect (__timeAreaW.TimeToPixel (node.startTime, rect) - 5, TIME_LABEL_HEIGHT + EVENT_PAD_HEIGHT + channelOrd * NODE_RECT_HEIGHT, 10, NODE_RECT_HEIGHT); //check start of the node rect width=5 if (clickRect.Contains (Event.current.mousePosition)) { __nodeSelected = node; resizeNodeStart = true; ev.Use (); } clickRect.x = __timeAreaW.TimeToPixel (node.startTime + node.duration, rect) - 5; //check the end of node rect width=5 if (clickRect.Contains (Event.current.mousePosition)) { __nodeSelected = node; resizeNodeEnd = true; ev.Use (); } clickRect.x = __timeAreaW.TimeToPixel (node.startTime, rect) + 5; clickRect.width = __timeAreaW.TimeToPixel (node.startTime + node.duration, rect) - clickRect.x - 5; if (clickRect.Contains (Event.current.mousePosition)) { if (ev.button == 0) { timeClickOffset = node.startTime - __timeAreaW.PixelToTime (Event.current.mousePosition.x, rect); dragNode = true; __nodeSelected = node; } if (ev.button == 1) { GenericMenu genericMenu = new GenericMenu (); genericMenu.AddItem (new GUIContent ("Remove"), false, this.RemoveNode, node); genericMenu.ShowAsContext (); __nodeSelected = node; } ev.Use (); } break; case EventType.ContextClick: //don't allow removing right click when play or record if (__sequence.isPlaying || __sequence.isRecording) break; clickRect = new Rect (0, 0, 0, NODE_RECT_HEIGHT); clickRect.x = __timeAreaW.TimeToPixel (node.startTime, rect); clickRect.y = TIME_LABEL_HEIGHT + EVENT_PAD_HEIGHT + channelOrd * NODE_RECT_HEIGHT; clickRect.width = __timeAreaW.TimeToPixel (node.startTime + node.duration, rect) - clickRect.x; if (clickRect.Contains (Event.current.mousePosition)) { GenericMenu genericMenu = new GenericMenu (); genericMenu.AddItem (new GUIContent ("Remove"), false, this.RemoveNode, node); genericMenu.ShowAsContext (); } break; } }
/// <summary> /// Removes the node. /// </summary> /// <param name="data">Data.</param> private void RemoveNode(object data) { SequenceNode node = data as SequenceNode; SequenceChannel sequenceChannel = __sequence.channels.Find (itm => itm.nodes.Exists (nd => nd.GetInstanceID () == node.GetInstanceID ())); if (node.source is AnimationClip) { if (node.index + 1 < sequenceChannel.nodes.Count)//if prev node exist reset its transition sequenceChannel.nodes [node.index + 1].transition = 0; //bypass transition // if (node.index - 1 > -1 && node.index + 1 < sequenceChannel.nodes.Count) { // UnityEditor.Animations.AnimatorController animatorController = (sequenceChannel.runtimeAnimatorController as UnityEditor.Animations.AnimatorController); // UnityEditor.Animations.AnimatorState statePrev = animatorController.GetStateBy (sequenceChannel.nodes [node.index - 1].stateNameHash); // // UnityEditor.Animations.AnimatorStateTransition transition = statePrev.transitions [0]; // transition.destinationState = animatorController.GetStateBy (sequenceChannel.nodes [node.index + 1].stateNameHash); // // } } //remove node sequenceChannel.nodes.Remove (node); if (sequenceChannel.runtimeAnimatorController != null)//remove AnimatorState (sequenceChannel.runtimeAnimatorController as UnityEditor.Animations.AnimatorController).RemoveStateWith (node.stateNameHash); int nodesCount = sequenceChannel.nodes.Count; //reindex nodes after remove for (int i=node.index; i<nodesCount; i++) sequenceChannel.nodes [i].index--; //if this removed node was last node => remove channel and move channels up(reindex) if (sequenceChannel.nodes.Count == 0) { //remove channel __sequence.channels.Remove (sequenceChannel); DestroyImmediate(sequenceChannel); } __nodeSelected = null; __sequence.timeCurrent = 0f; ResetChannelsTarget (); __needSave = true; Repaint (); }
/// <summary> /// Ons the sequence node start. /// </summary> /// <param name="node">Node.</param> public static void onSequenceNodeStart(SequenceNode node) { Debug.Log ("onSequenceNodeStart " + node.name); if (node.source is AudioClip) { AudioUtilW.PlayClip (node.source as AudioClip, 0, node.loop);//startSample doesn't work in this function???? } else if (node.source is MovieTexture) { MovieTexture movieTexture = node.source as MovieTexture; if (node.channel.target.tag == Tags.MAIN_CAMERA) {//==Camera.main Debug.Log (node.name + " RenderSettings.skybox isn't supported in EditMode"); //RenderSettings.skybox.mainTexture = movieTexture; } else { Renderer renderer = node.channel.target.GetComponent<Renderer> (); if (renderer != null) { renderer.material=new Material( Shader.Find("Unlit/Texture")); renderer.material.mainTexture = movieTexture; //renderer.sharedMaterial.mainTexture=movieTexture;//Instantiating material due to calling renderer.material during edit mode. This will leak materials into the scene. You most likely want to use renderer.sharedMaterial instead. //renderer.material.shader=Shader.Find("Unlit/Texture"); //remapp uv so it is not upsidedown //renderer.sharedMaterial.mainTexture = movieTexture; } } //This line would play movieTexture sound but if you have other sound would stack sound samplerr //if (movieTexture.audioClip != null) // AudioUtilW.PlayClip (movieTexture.audioClip, 0);//startSample doesn't work in this function???? // AudioSource audioSource = null; // if (movieTexture.audioClip != null) { // // audioSource = node.channel.target.GetComponent<AudioSource> (); // // if (audioSource == null) // audioSource = (AudioSource)node.channel.target.AddComponent (typeof(AudioSource)); // // audioSource.clip = movieTexture.audioClip; // // audioSource.PlayOneShot (audioSource.clip); // //audioSource.Play(); // // // } movieTexture.Play (); } }