private void OnInitialize() { GUILayout vertLayout = GUI.AddLayoutY(); GUILayout editorPanel = vertLayout.AddPanel(GUIOption.FixedHeight(400)); GUILayout buttonLayout = vertLayout.AddLayoutX(GUIOption.FixedHeight(40)); guiOK = new GUIButton(new LocEdString("OK")); guiCancel = new GUIButton(new LocEdString("Cancel")); guiOK.OnClick += OnOK; guiCancel.OnClick += OnCancel; CurveDrawOptions drawOptions = CurveDrawOptions.DrawKeyframes | CurveDrawOptions.DrawMarkers; if (curveB != null) { drawOptions |= CurveDrawOptions.DrawRange; } curveEditor = new GUICurveEditor(editorPanel, 600, 400, false, drawOptions); curveEditor.Redraw(); EdCurveDrawInfo[] drawinfo; if (curveB != null) { drawinfo = new [] { new EdCurveDrawInfo(curveA, Color.BansheeOrange), new EdCurveDrawInfo(curveB, Color.Green), }; } else { drawinfo = new [] { new EdCurveDrawInfo(curveA, Color.BansheeOrange), }; } curveEditor.SetCurves(drawinfo); curveEditor.CenterAndResize(true); buttonLayout.AddFlexibleSpace(); buttonLayout.AddElement(guiOK); buttonLayout.AddSpace(10); buttonLayout.AddElement(guiCancel); buttonLayout.AddFlexibleSpace(); EditorInput.OnPointerPressed += OnPointerPressed; EditorInput.OnPointerDoubleClick += OnPointerDoubleClicked; EditorInput.OnPointerMoved += OnPointerMoved; EditorInput.OnPointerReleased += OnPointerReleased; EditorInput.OnButtonUp += OnButtonUp; }
private void OnInitialize() { // TODO - Add methods to allow the window to be open with user-defined curve(s) // TODO - Add callbacks that trigger when user finishes editing // TODO - Add OK/Cancel buttons? Make the window modal? // TODO - Add a CurveField GUI element that can be used for curve preview, clicking on which opens this window curveEditor = new GUICurveEditor(this, this.GUI, 600, 400, false); curveEditor.Redraw(); EdAnimationCurve[] edAnimCurve = { new EdAnimationCurve(), new EdAnimationCurve() }; edAnimCurve[0].AddKeyframe(0.0f, 1.0f); edAnimCurve[0].AddKeyframe(5.0f, 3.0f); edAnimCurve[0].AddKeyframe(8.0f, -3.0f); edAnimCurve[0].AddKeyframe(15.0f, 2.0f); edAnimCurve[0].Apply(); edAnimCurve[1].AddKeyframe(0.0f, -3.0f); edAnimCurve[1].AddKeyframe(3.0f, 0.0f); edAnimCurve[1].AddKeyframe(10.0f, -1.0f); edAnimCurve[1].AddKeyframe(13.0f, -5.0f); edAnimCurve[1].Apply(); CurveDrawInfo[] drawinfo = { new CurveDrawInfo(edAnimCurve[0], Color.Green), new CurveDrawInfo(edAnimCurve[1], Color.Red), }; curveEditor.SetCurves(drawinfo); curveEditor.CenterAndResize(true); curveEditor.SetDrawRange(true); EditorInput.OnPointerPressed += OnPointerPressed; EditorInput.OnPointerDoubleClick += OnPointerDoubleClicked; EditorInput.OnPointerMoved += OnPointerMoved; EditorInput.OnPointerReleased += OnPointerReleased; EditorInput.OnButtonUp += OnButtonUp; }
/// <summary> /// Recreates the entire curve editor GUI depending on the currently selected scene object. /// </summary> private void RebuildGUI() { GUI.Clear(); guiCurveEditor = null; guiFieldDisplay = null; if (selectedSO == null) { GUILabel warningLbl = new GUILabel(new LocEdString("Select an object to animate in the Hierarchy or Scene windows.")); GUILayoutY vertLayout = GUI.AddLayoutY(); vertLayout.AddFlexibleSpace(); GUILayoutX horzLayout = vertLayout.AddLayoutX(); vertLayout.AddFlexibleSpace(); horzLayout.AddFlexibleSpace(); horzLayout.AddElement(warningLbl); horzLayout.AddFlexibleSpace(); return; } // Top button row GUIContent playIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.Play), new LocEdString("Play")); GUIContent recordIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.Record), new LocEdString("Record")); GUIContent prevFrameIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.FrameBack), new LocEdString("Previous frame")); GUIContent nextFrameIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.FrameForward), new LocEdString("Next frame")); GUIContent addKeyframeIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.AddKeyframe), new LocEdString("Add keyframe")); GUIContent addEventIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.AddEvent), new LocEdString("Add event")); GUIContent optionsIcon = new GUIContent(EditorBuiltin.GetLibraryWindowIcon(LibraryWindowIcon.Options), new LocEdString("Options")); playButton = new GUIToggle(playIcon, EditorStyles.Button); recordButton = new GUIToggle(recordIcon, EditorStyles.Button); prevFrameButton = new GUIButton(prevFrameIcon); frameInputField = new GUIIntField(); nextFrameButton = new GUIButton(nextFrameIcon); addKeyframeButton = new GUIButton(addKeyframeIcon); addEventButton = new GUIButton(addEventIcon); optionsButton = new GUIButton(optionsIcon); playButton.OnToggled += x => { if(x) SwitchState(State.Playback); else SwitchState(State.Normal); }; recordButton.OnToggled += x => { if (x) SwitchState(State.Recording); else SwitchState(State.Normal); }; prevFrameButton.OnClick += () => { SetCurrentFrame(currentFrameIdx - 1); switch (state) { case State.Recording: case State.Normal: PreviewFrame(currentFrameIdx); break; default: SwitchState(State.Normal); break; } }; frameInputField.OnChanged += x => { SetCurrentFrame(x); switch (state) { case State.Recording: case State.Normal: PreviewFrame(currentFrameIdx); break; default: SwitchState(State.Normal); break; } }; nextFrameButton.OnClick += () => { SetCurrentFrame(currentFrameIdx + 1); switch (state) { case State.Recording: case State.Normal: PreviewFrame(currentFrameIdx); break; default: SwitchState(State.Normal); break; } }; addKeyframeButton.OnClick += () => { SwitchState(State.Normal); guiCurveEditor.AddKeyFrameAtMarker(); }; addEventButton.OnClick += () => { SwitchState(State.Normal); guiCurveEditor.AddEventAtMarker(); }; optionsButton.OnClick += () => { Vector2I openPosition = ScreenToWindowPos(Input.PointerPosition); AnimationOptions dropDown = DropDownWindow.Open<AnimationOptions>(this, openPosition); dropDown.Initialize(this); }; // Property buttons addPropertyBtn = new GUIButton(new LocEdString("Add property")); delPropertyBtn = new GUIButton(new LocEdString("Delete selected")); addPropertyBtn.OnClick += () => { Action openPropertyWindow = () => { Vector2I windowPos = ScreenToWindowPos(Input.PointerPosition); FieldSelectionWindow fieldSelection = DropDownWindow.Open<FieldSelectionWindow>(this, windowPos); fieldSelection.OnFieldSelected += OnFieldAdded; }; if (clipInfo.clip == null) { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("Selected object doesn't have an animation clip assigned. Would you like to create" + " a new animation clip?"); DialogBox.Open(title, message, DialogBox.Type.YesNoCancel, type => { if (type == DialogBox.ResultType.Yes) { string clipSavePath; if (BrowseDialog.SaveFile(ProjectLibrary.ResourceFolder, "*.asset", out clipSavePath)) { SwitchState(State.Empty); clipSavePath = Path.ChangeExtension(clipSavePath, ".asset"); AnimationClip newClip = new AnimationClip(); ProjectLibrary.Create(newClip, clipSavePath); LoadAnimClip(newClip); Animation animation = selectedSO.GetComponent<Animation>(); if (animation == null) animation = selectedSO.AddComponent<Animation>(); animation.DefaultClip = newClip; EditorApplication.SetSceneDirty(); SwitchState(State.Normal); openPropertyWindow(); } } }); } else { if (clipInfo.isImported) { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("You cannot add/edit/remove curves from animation clips that" + " are imported from an external file."); DialogBox.Open(title, message, DialogBox.Type.OK); } else { SwitchState(State.Normal); openPropertyWindow(); } } }; delPropertyBtn.OnClick += () => { if (clipInfo.clip == null) return; SwitchState(State.Normal); if (clipInfo.isImported) { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("You cannot add/edit/remove curves from animation clips that" + " are imported from an external file."); DialogBox.Open(title, message, DialogBox.Type.OK); } else { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("Are you sure you want to remove all selected fields?"); DialogBox.Open(title, message, DialogBox.Type.YesNo, x => { if (x == DialogBox.ResultType.Yes) { RemoveSelectedFields(); ApplyClipChanges(); } }); } }; GUIPanel mainPanel = GUI.AddPanel(); GUIPanel backgroundPanel = GUI.AddPanel(1); GUILayout mainLayout = mainPanel.AddLayoutY(); buttonLayout = mainLayout.AddLayoutX(); buttonLayout.AddSpace(5); buttonLayout.AddElement(playButton); buttonLayout.AddElement(recordButton); buttonLayout.AddSpace(5); buttonLayout.AddElement(prevFrameButton); buttonLayout.AddElement(frameInputField); buttonLayout.AddElement(nextFrameButton); buttonLayout.AddSpace(5); buttonLayout.AddElement(addKeyframeButton); buttonLayout.AddElement(addEventButton); buttonLayout.AddSpace(5); buttonLayout.AddElement(optionsButton); buttonLayout.AddFlexibleSpace(); buttonLayoutHeight = playButton.Bounds.height; GUITexture buttonBackground = new GUITexture(null, EditorStyles.HeaderBackground); buttonBackground.Bounds = new Rect2I(0, 0, Width, buttonLayoutHeight); backgroundPanel.AddElement(buttonBackground); GUILayout contentLayout = mainLayout.AddLayoutX(); GUILayout fieldDisplayLayout = contentLayout.AddLayoutY(GUIOption.FixedWidth(FIELD_DISPLAY_WIDTH)); guiFieldDisplay = new GUIAnimFieldDisplay(fieldDisplayLayout, FIELD_DISPLAY_WIDTH, Height - buttonLayoutHeight * 2, selectedSO); guiFieldDisplay.OnEntrySelected += OnFieldSelected; GUILayout bottomButtonLayout = fieldDisplayLayout.AddLayoutX(); bottomButtonLayout.AddElement(addPropertyBtn); bottomButtonLayout.AddElement(delPropertyBtn); horzScrollBar = new GUIResizeableScrollBarH(); horzScrollBar.OnScrollOrResize += OnHorzScrollOrResize; vertScrollBar = new GUIResizeableScrollBarV(); vertScrollBar.OnScrollOrResize += OnVertScrollOrResize; GUITexture separator = new GUITexture(null, EditorStyles.Separator, GUIOption.FixedWidth(3)); contentLayout.AddElement(separator); GUILayout curveLayout = contentLayout.AddLayoutY(); GUILayout curveLayoutHorz = curveLayout.AddLayoutX(); GUILayout horzScrollBarLayout = curveLayout.AddLayoutX(); horzScrollBarLayout.AddElement(horzScrollBar); horzScrollBarLayout.AddFlexibleSpace(); editorPanel = curveLayoutHorz.AddPanel(); curveLayoutHorz.AddElement(vertScrollBar); curveLayoutHorz.AddFlexibleSpace(); scrollBarHeight = horzScrollBar.Bounds.height; scrollBarWidth = vertScrollBar.Bounds.width; Vector2I curveEditorSize = GetCurveEditorSize(); guiCurveEditor = new GUICurveEditor(this, editorPanel, curveEditorSize.x, curveEditorSize.y); guiCurveEditor.OnFrameSelected += OnFrameSelected; guiCurveEditor.OnEventAdded += OnEventsChanged; guiCurveEditor.OnEventModified += EditorApplication.SetProjectDirty; guiCurveEditor.OnEventDeleted += OnEventsChanged; guiCurveEditor.OnCurveModified += () => { SwitchState(State.Normal); ApplyClipChanges(); PreviewFrame(currentFrameIdx); EditorApplication.SetProjectDirty(); }; guiCurveEditor.OnClicked += () => { if(state != State.Recording) SwitchState(State.Normal); }; guiCurveEditor.Redraw(); horzScrollBar.SetWidth(curveEditorSize.x); vertScrollBar.SetHeight(curveEditorSize.y); UpdateScrollBarSize(); }
private void RebuildGUI() { GUI.Clear(); guiCurveEditor = null; guiFieldDisplay = null; if (selectedSO == null) { GUILabel warningLbl = new GUILabel(new LocEdString("Select an object to animate in the Hierarchy or Scene windows.")); GUILayoutY vertLayout = GUI.AddLayoutY(); vertLayout.AddFlexibleSpace(); GUILayoutX horzLayout = vertLayout.AddLayoutX(); vertLayout.AddFlexibleSpace(); horzLayout.AddFlexibleSpace(); horzLayout.AddElement(warningLbl); horzLayout.AddFlexibleSpace(); return; } // Top button row GUIContent playIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.Play), new LocEdString("Play")); GUIContent recordIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.Record), new LocEdString("Record")); GUIContent prevFrameIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.FrameBack), new LocEdString("Previous frame")); GUIContent nextFrameIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.FrameForward), new LocEdString("Next frame")); GUIContent addKeyframeIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.AddKeyframe), new LocEdString("Add keyframe")); GUIContent addEventIcon = new GUIContent(EditorBuiltin.GetAnimationWindowIcon(AnimationWindowIcon.AddEvent), new LocEdString("Add event")); GUIContent optionsIcon = new GUIContent(EditorBuiltin.GetLibraryWindowIcon(LibraryWindowIcon.Options), new LocEdString("Options")); playButton = new GUIButton(playIcon); recordButton = new GUIButton(recordIcon); prevFrameButton = new GUIButton(prevFrameIcon); frameInputField = new GUIIntField(); nextFrameButton = new GUIButton(nextFrameIcon); addKeyframeButton = new GUIButton(addKeyframeIcon); addEventButton = new GUIButton(addEventIcon); optionsButton = new GUIButton(optionsIcon); playButton.OnClick += () => { // TODO // - Record current state of the scene object hierarchy // - Evaluate all curves manually and update them // - On end, restore original values of the scene object hierarchy }; recordButton.OnClick += () => { // TODO // - Every frame read back current values of all the current curve's properties and assign it to the current frame }; prevFrameButton.OnClick += () => { SetCurrentFrame(currentFrameIdx - 1); }; frameInputField.OnChanged += SetCurrentFrame; nextFrameButton.OnClick += () => { SetCurrentFrame(currentFrameIdx + 1); }; addKeyframeButton.OnClick += () => { guiCurveEditor.AddKeyFrameAtMarker(); }; addEventButton.OnClick += () => { guiCurveEditor.AddEventAtMarker(); }; optionsButton.OnClick += () => { Vector2I openPosition = ScreenToWindowPos(Input.PointerPosition); AnimationOptions dropDown = DropDownWindow.Open <AnimationOptions>(this, openPosition); dropDown.Initialize(this); }; // Property buttons addPropertyBtn = new GUIButton(new LocEdString("Add property")); delPropertyBtn = new GUIButton(new LocEdString("Delete selected")); addPropertyBtn.OnClick += () => { Action openPropertyWindow = () => { Vector2I windowPos = ScreenToWindowPos(Input.PointerPosition); FieldSelectionWindow fieldSelection = DropDownWindow.Open <FieldSelectionWindow>(this, windowPos); fieldSelection.OnFieldSelected += OnFieldAdded; }; if (clipInfo.clip == null) { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("Selected object doesn't have an animation clip assigned. Would you like to create" + " a new animation clip?"); DialogBox.Open(title, message, DialogBox.Type.YesNoCancel, type => { if (type == DialogBox.ResultType.Yes) { string clipSavePath; if (BrowseDialog.SaveFile(ProjectLibrary.ResourceFolder, "*.asset", out clipSavePath)) { clipSavePath = Path.ChangeExtension(clipSavePath, ".asset"); AnimationClip newClip = new AnimationClip(); ProjectLibrary.Create(newClip, clipSavePath); LoadAnimClip(newClip); Animation animation = selectedSO.GetComponent <Animation>(); if (animation == null) { animation = selectedSO.AddComponent <Animation>(); } animation.DefaultClip = newClip; EditorApplication.SetSceneDirty(); openPropertyWindow(); } } }); } else { if (clipInfo.isImported) { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("You cannot add/edit/remove curves from animation clips that" + " are imported from an external file."); DialogBox.Open(title, message, DialogBox.Type.OK); } else { openPropertyWindow(); } } }; delPropertyBtn.OnClick += () => { if (clipInfo.clip == null) { return; } if (clipInfo.isImported) { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("You cannot add/edit/remove curves from animation clips that" + " are imported from an external file."); DialogBox.Open(title, message, DialogBox.Type.OK); } else { LocEdString title = new LocEdString("Warning"); LocEdString message = new LocEdString("Are you sure you want to remove all selected fields?"); DialogBox.Open(title, message, DialogBox.Type.YesNo, x => { if (x == DialogBox.ResultType.Yes) { RemoveSelectedFields(); } }); } }; GUIPanel mainPanel = GUI.AddPanel(); GUIPanel backgroundPanel = GUI.AddPanel(1); GUILayout mainLayout = mainPanel.AddLayoutY(); buttonLayout = mainLayout.AddLayoutX(); buttonLayout.AddSpace(5); buttonLayout.AddElement(playButton); buttonLayout.AddElement(recordButton); buttonLayout.AddSpace(5); buttonLayout.AddElement(prevFrameButton); buttonLayout.AddElement(frameInputField); buttonLayout.AddElement(nextFrameButton); buttonLayout.AddSpace(5); buttonLayout.AddElement(addKeyframeButton); buttonLayout.AddElement(addEventButton); buttonLayout.AddSpace(5); buttonLayout.AddElement(optionsButton); buttonLayout.AddFlexibleSpace(); buttonLayoutHeight = playButton.Bounds.height; GUITexture buttonBackground = new GUITexture(null, EditorStyles.HeaderBackground); buttonBackground.Bounds = new Rect2I(0, 0, Width, buttonLayoutHeight); backgroundPanel.AddElement(buttonBackground); GUILayout contentLayout = mainLayout.AddLayoutX(); GUILayout fieldDisplayLayout = contentLayout.AddLayoutY(GUIOption.FixedWidth(FIELD_DISPLAY_WIDTH)); guiFieldDisplay = new GUIAnimFieldDisplay(fieldDisplayLayout, FIELD_DISPLAY_WIDTH, Height - buttonLayoutHeight * 2, selectedSO); guiFieldDisplay.OnEntrySelected += OnFieldSelected; GUILayout bottomButtonLayout = fieldDisplayLayout.AddLayoutX(); bottomButtonLayout.AddElement(addPropertyBtn); bottomButtonLayout.AddElement(delPropertyBtn); horzScrollBar = new GUIResizeableScrollBarH(); horzScrollBar.OnScrollOrResize += OnHorzScrollOrResize; vertScrollBar = new GUIResizeableScrollBarV(); vertScrollBar.OnScrollOrResize += OnVertScrollOrResize; GUITexture separator = new GUITexture(null, EditorStyles.Separator, GUIOption.FixedWidth(3)); contentLayout.AddElement(separator); GUILayout curveLayout = contentLayout.AddLayoutY(); GUILayout curveLayoutHorz = curveLayout.AddLayoutX(); GUILayout horzScrollBarLayout = curveLayout.AddLayoutX(); horzScrollBarLayout.AddElement(horzScrollBar); horzScrollBarLayout.AddFlexibleSpace(); editorPanel = curveLayoutHorz.AddPanel(); curveLayoutHorz.AddElement(vertScrollBar); curveLayoutHorz.AddFlexibleSpace(); scrollBarHeight = horzScrollBar.Bounds.height; scrollBarWidth = vertScrollBar.Bounds.width; Vector2I curveEditorSize = GetCurveEditorSize(); guiCurveEditor = new GUICurveEditor(this, editorPanel, curveEditorSize.x, curveEditorSize.y); guiCurveEditor.OnFrameSelected += OnFrameSelected; guiCurveEditor.OnEventAdded += OnEventsChanged; guiCurveEditor.OnEventModified += EditorApplication.SetProjectDirty; guiCurveEditor.OnEventDeleted += OnEventsChanged; guiCurveEditor.OnCurveModified += EditorApplication.SetProjectDirty; guiCurveEditor.Redraw(); horzScrollBar.SetWidth(curveEditorSize.x); vertScrollBar.SetHeight(curveEditorSize.y); UpdateScrollBarSize(); }