Skip to content

Commit efa8307

Browse files
Merge pull request #452 from Unity-Technologies/staging
0.1.1 staging > master
2 parents 8b28a2f + 14f239f commit efa8307

File tree

105 files changed

+6658
-5427
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+6658
-5427
lines changed

Actions/Delete.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#if UNITY_EDITOR
22
using System;
3-
using UnityEditor.Experimental.EditorVR.Utilities;
43
using UnityEngine;
54

65
namespace UnityEditor.Experimental.EditorVR.Actions
@@ -19,6 +18,8 @@ public override void ExecuteAction()
1918
this.DeleteSceneObject(go);
2019
}
2120

21+
UnityEditor.Undo.IncrementCurrentGroup();
22+
2223
Selection.activeGameObject = null;
2324
}
2425
}

Actions/Icons/RedoIcon.png

+2-2
Loading

Actions/Icons/UndoIcon.png

+2-2
Loading

Editor/EditingContextManagerEditor.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ void Awake()
2121
public override void OnInspectorGUI()
2222
{
2323
GUILayout.Label("Available Contexts");
24-
EditingContextManager.DoGUI(m_ContextNames, ref m_SelectedContextIndex, () => { m_Settings.defaultContextName = m_ContextNames[m_SelectedContextIndex]; });
24+
25+
m_SelectedContextIndex = EditorGUILayout.Popup(string.Empty, m_SelectedContextIndex, m_ContextNames);
26+
if (GUI.changed)
27+
{
28+
m_Settings.defaultContextName = m_ContextNames[m_SelectedContextIndex];
29+
GUIUtility.ExitGUI();
30+
}
2531

2632
EditorGUILayout.Space();
2733

Editor/ProxyFeedbackEditor.cs

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#if UNITY_2017_2_OR_NEWER
2+
using System;
3+
using System.Collections.Generic;
4+
using UnityEditor.Experimental.EditorVR.Modules;
5+
using UnityEditor.Experimental.EditorVR.Proxies;
6+
using UnityEngine;
7+
8+
namespace UnityEditor.Experimental.EditorVR.UI
9+
{
10+
sealed class ProxyFeedbackEditor : EditorWindow
11+
{
12+
readonly Dictionary<Type, SerializedProxyFeedback> m_SerializedFeedback = new Dictionary<Type, SerializedProxyFeedback>();
13+
Vector2 m_Scroll;
14+
15+
[MenuItem("Edit/Project Settings/EditorXR/Proxy Feedback")]
16+
static void Init()
17+
{
18+
GetWindow<ProxyFeedbackEditor>("Proxy Feedback Editor").Show();
19+
}
20+
21+
void OnEnable()
22+
{
23+
Refresh();
24+
}
25+
26+
void OnGUI()
27+
{
28+
if (Event.current.Equals(Event.KeyboardEvent("^w")))
29+
{
30+
Close();
31+
GUIUtility.ExitGUI();
32+
}
33+
34+
if (GUILayout.Button("Reload Data"))
35+
Refresh();
36+
37+
if (GUILayout.Button("Clear Data"))
38+
{
39+
ClearData();
40+
Refresh();
41+
}
42+
43+
if (GUILayout.Button("Save Data"))
44+
{
45+
SaveData();
46+
Refresh();
47+
}
48+
49+
m_Scroll = GUILayout.BeginScrollView(m_Scroll);
50+
var hasFeedback = false;
51+
foreach (var kvp in m_SerializedFeedback)
52+
{
53+
GUILayout.Label(kvp.Key.Name, EditorStyles.boldLabel);
54+
DrawPreferences(kvp.Value);
55+
hasFeedback = true;
56+
}
57+
58+
if (!hasFeedback)
59+
GUILayout.Label("No serialized feedback");
60+
61+
GUILayout.EndScrollView();
62+
}
63+
64+
static void DrawPreferences(SerializedProxyFeedback feedback)
65+
{
66+
GUILayout.Label("Left Hand");
67+
DrawNode(feedback.leftNode);
68+
GUILayout.Label("Right Hand");
69+
DrawNode(feedback.rightNode);
70+
}
71+
72+
static void DrawNode(SerializedProxyNodeFeedback node)
73+
{
74+
var keys = node.keys;
75+
var values = node.values;
76+
for (var i = 0; i < keys.Length; i++)
77+
{
78+
var data = values[i];
79+
data.presentations = EditorGUILayout.IntField(keys[i].ToString(), data.presentations);
80+
}
81+
}
82+
83+
void Refresh()
84+
{
85+
m_SerializedFeedback.Clear();
86+
var preferences = SerializedPreferencesModule.DeserializePreferences(Core.EditorVR.serializedPreferences);
87+
if (preferences == null)
88+
return;
89+
90+
foreach (var kvp in preferences.items)
91+
{
92+
var type = kvp.Key;
93+
if (typeof(TwoHandedProxyBase).IsAssignableFrom(type))
94+
{
95+
var item = kvp.Value;
96+
Type payloadType = null;
97+
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
98+
{
99+
payloadType = assembly.GetType(item.payloadType);
100+
if (payloadType != null)
101+
break;
102+
}
103+
104+
if (payloadType == null)
105+
continue;
106+
107+
var payload = (SerializedProxyFeedback)JsonUtility.FromJson(item.payload, payloadType);
108+
m_SerializedFeedback[kvp.Key] = payload;
109+
}
110+
}
111+
}
112+
113+
static void ClearData()
114+
{
115+
var preferences = SerializedPreferencesModule.DeserializePreferences(Core.EditorVR.serializedPreferences);
116+
if (preferences == null)
117+
return;
118+
119+
foreach (var kvp in new Dictionary<Type, SerializedPreferencesModule.SerializedPreferenceItem>(preferences.items))
120+
{
121+
var type = kvp.Key;
122+
if (typeof(TwoHandedProxyBase).IsAssignableFrom(type))
123+
preferences.Remove(type);
124+
}
125+
126+
Core.EditorVR.serializedPreferences = JsonUtility.ToJson(preferences);
127+
}
128+
129+
void SaveData()
130+
{
131+
var preferences = SerializedPreferencesModule.DeserializePreferences(Core.EditorVR.serializedPreferences);
132+
if (preferences == null)
133+
return;
134+
135+
var items = preferences.items;
136+
foreach (var kvp in m_SerializedFeedback)
137+
{
138+
items[kvp.Key].payload = JsonUtility.ToJson(kvp.Value);
139+
}
140+
141+
Core.EditorVR.serializedPreferences = JsonUtility.ToJson(preferences);
142+
}
143+
}
144+
}
145+
#endif

Editor/ProxyFeedbackEditor.cs.meta

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Menus/MainMenu/MainMenu.cs

+69-13
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia
1616
IRequestFeedback
1717
{
1818
const string k_SettingsMenuSectionName = "Settings";
19+
const float k_MaxFlickDuration = 0.3f;
1920

2021
[SerializeField]
2122
ActionMap m_ActionMap;
@@ -43,6 +44,8 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia
4344
MainMenuUI m_MainMenuUI;
4445
float m_LastRotationInput;
4546
MenuHideFlags m_MenuHideFlags = MenuHideFlags.Hidden;
47+
float m_RotationInputStartValue;
48+
float m_RotationInputStartTime;
4649
readonly Dictionary<Type, MainMenuButton> m_ToolButtons = new Dictionary<Type, MainMenuButton>();
4750
readonly Dictionary<ISettingsMenuProvider, GameObject> m_SettingsMenus = new Dictionary<ISettingsMenuProvider, GameObject>();
4851
readonly Dictionary<ISettingsMenuItemProvider, GameObject> m_SettingsMenuItems = new Dictionary<ISettingsMenuItemProvider, GameObject>();
@@ -53,7 +56,6 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia
5356
public List<Type> menuWorkspaces { private get; set; }
5457
public Dictionary<KeyValuePair<Type, Transform>, ISettingsMenuProvider> settingsMenuProviders { get; set; }
5558
public Dictionary<KeyValuePair<Type, Transform>, ISettingsMenuItemProvider> settingsMenuItemProviders { get; set; }
56-
public List<ActionMenuData> menuActions { get; set; }
5759
public Transform targetRayOrigin { private get; set; }
5860
public Node node { get; set; }
5961

@@ -62,6 +64,7 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia
6264
public Transform rayOrigin { private get; set; }
6365

6466
public Bounds localBounds { get { return m_MainMenuUI.localBounds; } }
67+
public int priority { get { return 0; } }
6568

6669
public bool focus { get { return m_MainMenuUI.hovering; } }
6770

@@ -142,23 +145,53 @@ public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeCon
142145
var mainMenuInput = (MainMenuInput)input;
143146
var rotationInput = -mainMenuInput.rotate.rawValue;
144147

145-
consumeControl(mainMenuInput.rotate);
146-
consumeControl(mainMenuInput.blockY);
147-
148148
const float kFlickDeltaThreshold = 0.5f;
149-
if ((this.GetDeviceType() != DeviceType.Vive && Mathf.Abs(rotationInput) >= kFlickDeltaThreshold
150-
&& Mathf.Abs(m_LastRotationInput) < kFlickDeltaThreshold) || mainMenuInput.flickFace.wasJustReleased)
149+
150+
if (this.GetDeviceType() == DeviceType.Vive)
151151
{
152-
m_MainMenuUI.targetFaceIndex += (int)Mathf.Sign(rotationInput);
153-
this.Pulse(node, m_FaceRotationPulse);
152+
if (!Mathf.Approximately(rotationInput, 0f))
153+
{
154+
var time = Time.time;
155+
if (Mathf.Approximately(m_LastRotationInput, 0f))
156+
{
157+
// Touch began
158+
m_RotationInputStartValue = rotationInput;
159+
m_RotationInputStartTime = time;
160+
}
161+
else
162+
{
163+
// Touch held
164+
var distance = rotationInput - m_RotationInputStartValue;
165+
var lastDistance = m_LastRotationInput - m_RotationInputStartValue;
166+
if (Mathf.Abs(distance) >= kFlickDeltaThreshold
167+
&& Mathf.Abs(lastDistance) < kFlickDeltaThreshold
168+
&& time - m_RotationInputStartTime < k_MaxFlickDuration)
169+
{
170+
m_RotationInputStartValue = rotationInput;
171+
m_RotationInputStartTime = time;
172+
if (!m_MainMenuUI.rotating)
173+
{
174+
FlickMenu(distance);
175+
}
176+
}
177+
}
178+
}
179+
}
180+
else if (Mathf.Abs(rotationInput) >= kFlickDeltaThreshold
181+
&& Mathf.Abs(m_LastRotationInput) < kFlickDeltaThreshold)
182+
{
183+
FlickMenu(rotationInput);
154184
}
155-
156-
if (m_MenuHideFlags == 0)
157-
consumeControl(mainMenuInput.flickFace);
158185

159186
m_LastRotationInput = rotationInput;
160187
}
161188

189+
void FlickMenu(float rotationInput)
190+
{
191+
m_MainMenuUI.targetFaceIndex += (int)Mathf.Sign(rotationInput);
192+
this.Pulse(node, m_FaceRotationPulse);
193+
}
194+
162195
void OnDestroy()
163196
{
164197
if (m_MainMenuUI)
@@ -299,6 +332,11 @@ void OnButtonHovered(Transform rayOrigin, Type buttonType, string buttonDescript
299332
this.PreviewInToolMenuButton(rayOrigin, buttonType, buttonDescription);
300333
}
301334

335+
void OnToggleHovered(Transform rayOrigin)
336+
{
337+
this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_ButtonHoverPulse);
338+
}
339+
302340
void SendVisibilityPulse()
303341
{
304342
this.Pulse(node, m_MenuHideFlags == 0 ? m_HidePulse : m_ShowPulse);
@@ -333,12 +371,29 @@ void AddSettingsMenu(ISettingsMenuProvider provider, MainMenuUI.ButtonData butto
333371
{
334372
buttonData.sectionName = k_SettingsMenuSectionName;
335373

336-
CreateFaceButton(buttonData, tooltip, () =>
374+
var button = CreateFaceButton(buttonData, tooltip, () =>
337375
{
338376
var instance = m_MainMenuUI.AddSubmenu(k_SettingsMenuSectionName, provider.settingsMenuPrefab);
339377
m_SettingsMenus[provider] = instance;
340378
provider.settingsMenuInstance = instance;
379+
AddToggleHaptics(instance);
341380
});
381+
382+
button.hovered += OnButtonHovered;
383+
button.clicked += OnButtonClicked;
384+
}
385+
386+
void AddToggleHaptics(GameObject menuInstance)
387+
{
388+
var toggles = menuInstance.GetComponentsInChildren<MainMenuToggle>();
389+
if (toggles != null && toggles.Length > 0)
390+
{
391+
foreach (var toggle in toggles)
392+
{
393+
toggle.hovered += OnToggleHovered;
394+
toggle.clicked += OnButtonClicked;
395+
}
396+
}
342397
}
343398

344399
public void RemoveSettingsMenu(ISettingsMenuProvider provider)
@@ -359,6 +414,7 @@ public void AddSettingsMenuItem(ISettingsMenuItemProvider provider)
359414
var instance = m_MainMenuUI.CreateCustomButton(provider.settingsMenuItemPrefab, k_SettingsMenuSectionName);
360415
m_SettingsMenuItems[provider] = instance;
361416
provider.settingsMenuItemInstance = instance;
417+
AddToggleHaptics(instance);
362418
}
363419

364420
public void RemoveSettingsMenuItem(ISettingsMenuItemProvider provider)
@@ -376,7 +432,7 @@ public void RemoveSettingsMenuItem(ISettingsMenuItemProvider provider)
376432

377433
void ShowFeedback()
378434
{
379-
var tooltipText = this.GetDeviceType() == DeviceType.Vive ? "Press to Rotate Menu" : "Rotate Menu";
435+
var tooltipText = this.GetDeviceType() == DeviceType.Vive ? "Swipe to Rotate Menu" : "Rotate Menu";
380436
List<VRInputDevice.VRControl> controls;
381437
if (m_Controls.TryGetValue("FlickFace", out controls))
382438
{

0 commit comments

Comments
 (0)