Skip to content

Persistent undo menu#407

Merged
mtschoen-unity merged 44 commits into
developmentfrom
features/jono/undo-redo-flick
Dec 9, 2017
Merged

Persistent undo menu#407
mtschoen-unity merged 44 commits into
developmentfrom
features/jono/undo-redo-flick

Conversation

@jono-unity

Copy link
Copy Markdown
Contributor

Purpose of this PR

Implement a persistent undo/redo menu: any controller without a radial menu currently open can undo/redo. On Touch, click in the joystick and then flick left or right; on Vive, click in left/right on the touchpad.

This change necessitated changing the main menu behavior on Vive: it is now controlled by swiping the touchpad, rather than clicking in.

Testing status

Tested on Vive and Rift in various scenes. Some objects and operations take a long time to undo/redo, and undo/redo behavior can be inconsistent. This seems to be true across all undo/redo functionality in EVR, as I saw the same inconsistency & delay on some objects when also testing with the existing radial menu actions.

Technical risk

Medium: As this changes behavior in MainMenu, and also is a nearly-always-open menu consuming stick/pad input, the UX & interaction with other tools impact is non-trivial.

Comments to reviewers

-Note the inconsistent undo/redo behavior I described in testing status -- this is a big issue, out of the scope of this PR.
-I'm not fully satisfied with the MainMenu swipe behavior yet and intend to work that some more (and would love feedback about it) -- but wanted to get this in front of everyone asap.

@dunity dunity left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall nice work!

IMO there should be a visual means of denoting (perhaps with an arrow color and/or size change, etc) that there is an available undo or redo action that can be performed. I'm not really sure when I can or can't undo (mostly due to the broken undo/redo issue).

Aside from the PR comments, I ran into an issue that randomly showed itself when enabling and disabling the Radial menu. "Coroutine couldn't be started because the the game object 'UndoMenu(Clone)' is inactive!" Likely the undo menu needs to stopAllCoroutines on disable, or something along those lines.

In addition, on a few occassions, when quickly undoing and redoing on the left touch controller, I would get the Undo tooltip/feedback to lock, and not fade away, or stop displaying any longer. Though I couldn't find a reliable repro for that.

Comment thread Menus/MainMenu/MainMenu.cs Outdated
@@ -1,5 +1,6 @@
#if UNITY_EDITOR
using System;
using System.Collections;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove using

Comment thread Menus/MainMenu/MainMenu.cs Outdated
{
m_MainMenuUI.targetFaceIndex += (int)Mathf.Sign(rotationInput);
this.Pulse(node, m_FaceRotationPulse);
if (rotationInput != 0f)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!Mathf.Approximately(rotationInput, 0f)

Comment thread Menus/MainMenu/MainMenu.cs Outdated
this.Pulse(node, m_FaceRotationPulse);
if (rotationInput != 0f)
{
if (m_LastRotationInput == 0f)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mathf.Approximately(m_LastRotationInput, 0f)

Comment thread Menus/UndoMenu/Scripts/UndoMenuUI.cs Outdated
var currentDuration = 0f;
while (transitionAmount < 1f)
{
m_UndoButtonMaterial.SetColor(k_MaterialColorProperty, Color.Lerp(undoStartingColor, targetColor, transitionAmount));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use SmoothInOutLerpFloat()
var smoothAmount = MathUtilsExt.SmoothInOutLerpFloat(transitionAmount);
m_UndoButtonMaterial.SetColor(k_MaterialColorProperty, Color.Lerp(undoStartingColor, targetColor, smoothAmount));
m_RedoButtonMaterial.SetColor(k_MaterialColorProperty, Color.Lerp(redoStartingColor, targetColor, smoothAmount));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orrrr maybe AnimateProperty, once that lands? I'm inclined to punt for that reason.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've switched to SmoothInOutLerp for now, but yep, that AnimateProperty sounds pretty good. Where's that branchwise?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread Menus/UndoMenu/Scripts/UndoMenuUI.cs Outdated
targetColor.a = k_DisengagedAlpha;
while (transitionAmount < 1f)
{
var currentColor = Color.Lerp(startingColor, targetColor, transitionAmount);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lerp using MathUtilsExt.SmoothInOutLerpFloat(transitionAmount), as mentioned above.

Comment thread Menus/UndoMenu/Scripts/UndoMenuUI.cs Outdated
ObjectUtils.Destroy(m_RedoButtonMaterial);
}

public void Setup()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove Setup function. Disable the UI gameObject in UndoMenu's Start() function.

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated
m_UndoMenuUI.alternateMenuOrigin = alternateMenuOrigin;
m_UndoMenuUI.actions = menuActions;
this.ConnectInterfaces(m_UndoMenuUI); // Connect interfaces before performing setup on the UI
m_UndoMenuUI.Setup();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove setup method, just disable UI gameobject here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Though we use them in quite a few places, our goal is to avoid Setup methods where possible.

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated
void ShowFeedback()
{
List<VRInputDevice.VRControl> controls;
if (m_Controls.TryGetValue("Engage", out controls))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use singular class-level const string for "Engage"

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated
void ShowUndoPerformedFeedback(bool undo)
{
List<VRInputDevice.VRControl> controls;
if (m_Controls.TryGetValue("Engage", out controls))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use singular class-level const string for "Engage"

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated

if (undoRedoPerformed)
{
consumeControl(undoMenuInput.navigateX);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the AcceptInputAfterStickReleased coroutine be stopped here if currently running?

@mtschoen-unity mtschoen-unity left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Way to grok the coventions and common patterns right off the bat.

I was able to find an error after monkeying around for a bit (the student becomes the master!)

Coroutine couldn't be started because the the game object 'UndoMenu(Clone)' is inactive!
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

My guess is that it's from setting the gameobject to inactive in the visibility property without stopping all coroutines.

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated

public Node node { get; set; }

public event Action<Transform> itemWasSelected;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a warning about this being unused. Does UndoMenu need to be an IAlternateMenu? Could it just be an IMenu? I think we can still just attach it to the alternate menu origin but make it not actually be a IAlternateMenu. Same goes with IUsesRayOrigin (Included in IAlternateMenu). We don't seem to use/need it.

It looks like this will require a refactor of SpawnAlternateMenu, etc. but to look at it, all we do is check that it's the right interface, add a component, and connect interfaces. I think we could make it generic no problem.

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated

readonly BindingDictionary m_Controls = new BindingDictionary();

public Transform rayOrigin { private get; set; }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. We should kill it. See comment below.

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated
m_UndoMenuUI.alternateMenuOrigin = alternateMenuOrigin;
m_UndoMenuUI.actions = menuActions;
this.ConnectInterfaces(m_UndoMenuUI); // Connect interfaces before performing setup on the UI
m_UndoMenuUI.Setup();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Though we use them in quite a few places, our goal is to avoid Setup methods where possible.

Comment thread Menus/UndoMenu/Scripts/UndoMenuUI.cs Outdated
var currentDuration = 0f;
while (transitionAmount < 1f)
{
m_UndoButtonMaterial.SetColor(k_MaterialColorProperty, Color.Lerp(undoStartingColor, targetColor, transitionAmount));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orrrr maybe AnimateProperty, once that lands? I'm inclined to punt for that reason.

{
if (m_Engaged == value)
return;
m_Engaged = value;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blank line after return;

Comment thread Menus/UndoMenu/UndoMenu.cs Outdated
if (visible)
ShowFeedback();
else
this.ClearFeedbackRequests();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... this doesn't allocate, but it does show up when I'm deep profiling (iterates over all feedback). I don't think it's a major worry but we should avoid spamming this method every frame. Feel free to punt until after this PR.

Comment thread Menus/UndoMenu/Scripts/UndoMenuUI.cs Outdated
}
}

List<ActionMenuData> m_Actions;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we do anything with actions? Is this just a vestige of RadialMenu? If so, should be removed as part of the not-alternate-menu refactor.


m_Visible = value;

gameObject.SetActive(value);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Careful with this. We might want to kill coroutines before setting active to false.

@AndrewTHEManeri AndrewTHEManeri left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing really to add except the note about using DateTime.

Looks solid, good work

Comment thread Menus/MainMenu/MainMenu.cs Outdated
float m_LastRotationInput;
MenuHideFlags m_MenuHideFlags = MenuHideFlags.Hidden;
float m_RotationInputStartValue;
DateTime m_RotationInputStartTime;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty unusual for us to use DateTime, normally we just use float since that is what Unity's Time class gives us

@mtschoen-unity

Copy link
Copy Markdown
Collaborator

I did the IAlternateMenu refactor after merging with dev. Dev merge brought up a bug where a tooltip, if it is already visible, will not update its text if it changes and is shown again. Fixed that.

mtschoen-unity and others added 21 commits December 5, 2017 01:25
…th CCU-wrapped call to that fix to fix "Driving RectTransform" undo issue
…e alternate menus can overlap the Tools Menu;

Remove left/right to undo/redo in AnnotationTool; Consume stick press input in LocomotionTool while two-handed-scaling
…ditorVR into features/jono/undo-redo-flick

# Conflicts:
#	Menus/MainMenu/MainMenu.cs
#	Menus/RadialMenu/RadialMenu.cs
#	Scripts/Core/EditorVR.Menus.cs
#	Scripts/Core/EditorVR.cs
#	Tools/AnnotationTool/AnnotationTool.cs
#	Tools/AnnotationTool/UserInterface/ColorPickerActivator.cs
#	Tools/CreatePrimitiveTool/CreatePrimitiveTool.cs
#	Tools/SelectionTool/SelectionTool.cs
…-Technologies/EditorVR into features/jono/undo-redo-flick

# Conflicts:
#	Scripts/Core/EditorVR.cs
…raw the next one;

Remove undo/redo buttons from AnnotationUI
…ditorVR into features/jono/undo-redo-flick

# Conflicts:
#	Menus/MainMenu/MainMenu.cs
#	Scripts/Core/EditorVR.cs
@mtschoen-unity
mtschoen-unity force-pushed the features/jono/undo-redo-flick branch from fcbba41 to 0d8c9f6 Compare December 9, 2017 06:33
@mtschoen-unity

Copy link
Copy Markdown
Collaborator

Conflicts resolved locally. Performing Github merge.

@mtschoen-unity
mtschoen-unity merged commit d43614e into development Dec 9, 2017
@mtschoen-unity
mtschoen-unity deleted the features/jono/undo-redo-flick branch December 9, 2017 06:57
@mtschoen-unity mtschoen-unity added this to the 0.1.1 milestone Dec 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants