diff --git a/Actions/Delete.cs b/Actions/Delete.cs index 64b24043a..96327a56b 100644 --- a/Actions/Delete.cs +++ b/Actions/Delete.cs @@ -1,6 +1,5 @@ #if UNITY_EDITOR using System; -using UnityEditor.Experimental.EditorVR.Utilities; using UnityEngine; namespace UnityEditor.Experimental.EditorVR.Actions @@ -19,6 +18,8 @@ public override void ExecuteAction() this.DeleteSceneObject(go); } + UnityEditor.Undo.IncrementCurrentGroup(); + Selection.activeGameObject = null; } } diff --git a/Actions/Icons/RedoIcon.png b/Actions/Icons/RedoIcon.png index f868a3d61..696441634 100644 --- a/Actions/Icons/RedoIcon.png +++ b/Actions/Icons/RedoIcon.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72aecdcd01888c198ddceb3ac2bad7b0f47138e2e76e043de5c3797365789a76 -size 5426 +oid sha256:efda6f73c3b1b47ea50ce98a8636e8c0a002bb6230fd772023e0c75a8a17b20e +size 21741 diff --git a/Actions/Icons/UndoIcon.png b/Actions/Icons/UndoIcon.png index 2ce15dfb8..fe0eb6de6 100644 --- a/Actions/Icons/UndoIcon.png +++ b/Actions/Icons/UndoIcon.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c23ae97e3d31c63fea4f228de859f652f1bc8d1a56c685a6d78935467bdbe12 -size 5724 +oid sha256:c32c3e9f91275bf6f10ce0b4f1be291689f8ca62802a3bdcdf58877d7037f545 +size 7082 diff --git a/Editor/EditingContextManagerEditor.cs b/Editor/EditingContextManagerEditor.cs index 42660c7c9..371469302 100644 --- a/Editor/EditingContextManagerEditor.cs +++ b/Editor/EditingContextManagerEditor.cs @@ -21,7 +21,13 @@ void Awake() public override void OnInspectorGUI() { GUILayout.Label("Available Contexts"); - EditingContextManager.DoGUI(m_ContextNames, ref m_SelectedContextIndex, () => { m_Settings.defaultContextName = m_ContextNames[m_SelectedContextIndex]; }); + + m_SelectedContextIndex = EditorGUILayout.Popup(string.Empty, m_SelectedContextIndex, m_ContextNames); + if (GUI.changed) + { + m_Settings.defaultContextName = m_ContextNames[m_SelectedContextIndex]; + GUIUtility.ExitGUI(); + } EditorGUILayout.Space(); diff --git a/Editor/ProxyFeedbackEditor.cs b/Editor/ProxyFeedbackEditor.cs new file mode 100644 index 000000000..0e739d505 --- /dev/null +++ b/Editor/ProxyFeedbackEditor.cs @@ -0,0 +1,145 @@ +#if UNITY_2017_2_OR_NEWER +using System; +using System.Collections.Generic; +using UnityEditor.Experimental.EditorVR.Modules; +using UnityEditor.Experimental.EditorVR.Proxies; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR.UI +{ + sealed class ProxyFeedbackEditor : EditorWindow + { + readonly Dictionary m_SerializedFeedback = new Dictionary(); + Vector2 m_Scroll; + + [MenuItem("Edit/Project Settings/EditorXR/Proxy Feedback")] + static void Init() + { + GetWindow("Proxy Feedback Editor").Show(); + } + + void OnEnable() + { + Refresh(); + } + + void OnGUI() + { + if (Event.current.Equals(Event.KeyboardEvent("^w"))) + { + Close(); + GUIUtility.ExitGUI(); + } + + if (GUILayout.Button("Reload Data")) + Refresh(); + + if (GUILayout.Button("Clear Data")) + { + ClearData(); + Refresh(); + } + + if (GUILayout.Button("Save Data")) + { + SaveData(); + Refresh(); + } + + m_Scroll = GUILayout.BeginScrollView(m_Scroll); + var hasFeedback = false; + foreach (var kvp in m_SerializedFeedback) + { + GUILayout.Label(kvp.Key.Name, EditorStyles.boldLabel); + DrawPreferences(kvp.Value); + hasFeedback = true; + } + + if (!hasFeedback) + GUILayout.Label("No serialized feedback"); + + GUILayout.EndScrollView(); + } + + static void DrawPreferences(SerializedProxyFeedback feedback) + { + GUILayout.Label("Left Hand"); + DrawNode(feedback.leftNode); + GUILayout.Label("Right Hand"); + DrawNode(feedback.rightNode); + } + + static void DrawNode(SerializedProxyNodeFeedback node) + { + var keys = node.keys; + var values = node.values; + for (var i = 0; i < keys.Length; i++) + { + var data = values[i]; + data.presentations = EditorGUILayout.IntField(keys[i].ToString(), data.presentations); + } + } + + void Refresh() + { + m_SerializedFeedback.Clear(); + var preferences = SerializedPreferencesModule.DeserializePreferences(Core.EditorVR.serializedPreferences); + if (preferences == null) + return; + + foreach (var kvp in preferences.items) + { + var type = kvp.Key; + if (typeof(TwoHandedProxyBase).IsAssignableFrom(type)) + { + var item = kvp.Value; + Type payloadType = null; + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + payloadType = assembly.GetType(item.payloadType); + if (payloadType != null) + break; + } + + if (payloadType == null) + continue; + + var payload = (SerializedProxyFeedback)JsonUtility.FromJson(item.payload, payloadType); + m_SerializedFeedback[kvp.Key] = payload; + } + } + } + + static void ClearData() + { + var preferences = SerializedPreferencesModule.DeserializePreferences(Core.EditorVR.serializedPreferences); + if (preferences == null) + return; + + foreach (var kvp in new Dictionary(preferences.items)) + { + var type = kvp.Key; + if (typeof(TwoHandedProxyBase).IsAssignableFrom(type)) + preferences.Remove(type); + } + + Core.EditorVR.serializedPreferences = JsonUtility.ToJson(preferences); + } + + void SaveData() + { + var preferences = SerializedPreferencesModule.DeserializePreferences(Core.EditorVR.serializedPreferences); + if (preferences == null) + return; + + var items = preferences.items; + foreach (var kvp in m_SerializedFeedback) + { + items[kvp.Key].payload = JsonUtility.ToJson(kvp.Value); + } + + Core.EditorVR.serializedPreferences = JsonUtility.ToJson(preferences); + } + } +} +#endif diff --git a/Editor/ProxyFeedbackEditor.cs.meta b/Editor/ProxyFeedbackEditor.cs.meta new file mode 100644 index 000000000..de6675524 --- /dev/null +++ b/Editor/ProxyFeedbackEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d3a9ecd7de8ff2c4fa4a85c66a8feda8 +timeCreated: 1486770624 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/MainMenu/MainMenu.cs b/Menus/MainMenu/MainMenu.cs index 86aa8d44a..90e12a1bb 100644 --- a/Menus/MainMenu/MainMenu.cs +++ b/Menus/MainMenu/MainMenu.cs @@ -16,6 +16,7 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia IRequestFeedback { const string k_SettingsMenuSectionName = "Settings"; + const float k_MaxFlickDuration = 0.3f; [SerializeField] ActionMap m_ActionMap; @@ -43,6 +44,8 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia MainMenuUI m_MainMenuUI; float m_LastRotationInput; MenuHideFlags m_MenuHideFlags = MenuHideFlags.Hidden; + float m_RotationInputStartValue; + float m_RotationInputStartTime; readonly Dictionary m_ToolButtons = new Dictionary(); readonly Dictionary m_SettingsMenus = new Dictionary(); readonly Dictionary m_SettingsMenuItems = new Dictionary(); @@ -53,7 +56,6 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia public List menuWorkspaces { private get; set; } public Dictionary, ISettingsMenuProvider> settingsMenuProviders { get; set; } public Dictionary, ISettingsMenuItemProvider> settingsMenuItemProviders { get; set; } - public List menuActions { get; set; } public Transform targetRayOrigin { private get; set; } public Node node { get; set; } @@ -62,6 +64,7 @@ sealed class MainMenu : MonoBehaviour, IMainMenu, IConnectInterfaces, IInstantia public Transform rayOrigin { private get; set; } public Bounds localBounds { get { return m_MainMenuUI.localBounds; } } + public int priority { get { return 0; } } public bool focus { get { return m_MainMenuUI.hovering; } } @@ -142,23 +145,53 @@ public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeCon var mainMenuInput = (MainMenuInput)input; var rotationInput = -mainMenuInput.rotate.rawValue; - consumeControl(mainMenuInput.rotate); - consumeControl(mainMenuInput.blockY); - const float kFlickDeltaThreshold = 0.5f; - if ((this.GetDeviceType() != DeviceType.Vive && Mathf.Abs(rotationInput) >= kFlickDeltaThreshold - && Mathf.Abs(m_LastRotationInput) < kFlickDeltaThreshold) || mainMenuInput.flickFace.wasJustReleased) + + if (this.GetDeviceType() == DeviceType.Vive) { - m_MainMenuUI.targetFaceIndex += (int)Mathf.Sign(rotationInput); - this.Pulse(node, m_FaceRotationPulse); + if (!Mathf.Approximately(rotationInput, 0f)) + { + var time = Time.time; + if (Mathf.Approximately(m_LastRotationInput, 0f)) + { + // Touch began + m_RotationInputStartValue = rotationInput; + m_RotationInputStartTime = time; + } + else + { + // Touch held + var distance = rotationInput - m_RotationInputStartValue; + var lastDistance = m_LastRotationInput - m_RotationInputStartValue; + if (Mathf.Abs(distance) >= kFlickDeltaThreshold + && Mathf.Abs(lastDistance) < kFlickDeltaThreshold + && time - m_RotationInputStartTime < k_MaxFlickDuration) + { + m_RotationInputStartValue = rotationInput; + m_RotationInputStartTime = time; + if (!m_MainMenuUI.rotating) + { + FlickMenu(distance); + } + } + } + } + } + else if (Mathf.Abs(rotationInput) >= kFlickDeltaThreshold + && Mathf.Abs(m_LastRotationInput) < kFlickDeltaThreshold) + { + FlickMenu(rotationInput); } - - if (m_MenuHideFlags == 0) - consumeControl(mainMenuInput.flickFace); m_LastRotationInput = rotationInput; } + void FlickMenu(float rotationInput) + { + m_MainMenuUI.targetFaceIndex += (int)Mathf.Sign(rotationInput); + this.Pulse(node, m_FaceRotationPulse); + } + void OnDestroy() { if (m_MainMenuUI) @@ -299,6 +332,11 @@ void OnButtonHovered(Transform rayOrigin, Type buttonType, string buttonDescript this.PreviewInToolMenuButton(rayOrigin, buttonType, buttonDescription); } + void OnToggleHovered(Transform rayOrigin) + { + this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_ButtonHoverPulse); + } + void SendVisibilityPulse() { this.Pulse(node, m_MenuHideFlags == 0 ? m_HidePulse : m_ShowPulse); @@ -333,12 +371,29 @@ void AddSettingsMenu(ISettingsMenuProvider provider, MainMenuUI.ButtonData butto { buttonData.sectionName = k_SettingsMenuSectionName; - CreateFaceButton(buttonData, tooltip, () => + var button = CreateFaceButton(buttonData, tooltip, () => { var instance = m_MainMenuUI.AddSubmenu(k_SettingsMenuSectionName, provider.settingsMenuPrefab); m_SettingsMenus[provider] = instance; provider.settingsMenuInstance = instance; + AddToggleHaptics(instance); }); + + button.hovered += OnButtonHovered; + button.clicked += OnButtonClicked; + } + + void AddToggleHaptics(GameObject menuInstance) + { + var toggles = menuInstance.GetComponentsInChildren(); + if (toggles != null && toggles.Length > 0) + { + foreach (var toggle in toggles) + { + toggle.hovered += OnToggleHovered; + toggle.clicked += OnButtonClicked; + } + } } public void RemoveSettingsMenu(ISettingsMenuProvider provider) @@ -359,6 +414,7 @@ public void AddSettingsMenuItem(ISettingsMenuItemProvider provider) var instance = m_MainMenuUI.CreateCustomButton(provider.settingsMenuItemPrefab, k_SettingsMenuSectionName); m_SettingsMenuItems[provider] = instance; provider.settingsMenuItemInstance = instance; + AddToggleHaptics(instance); } public void RemoveSettingsMenuItem(ISettingsMenuItemProvider provider) @@ -376,7 +432,7 @@ public void RemoveSettingsMenuItem(ISettingsMenuItemProvider provider) void ShowFeedback() { - var tooltipText = this.GetDeviceType() == DeviceType.Vive ? "Press to Rotate Menu" : "Rotate Menu"; + var tooltipText = this.GetDeviceType() == DeviceType.Vive ? "Swipe to Rotate Menu" : "Rotate Menu"; List controls; if (m_Controls.TryGetValue("FlickFace", out controls)) { diff --git a/Menus/MainMenu/MainMenuInput.asset b/Menus/MainMenu/MainMenuInput.asset index e9f0131ac..9b463d4c1 100644 --- a/Menus/MainMenu/MainMenuInput.asset +++ b/Menus/MainMenu/MainMenuInput.asset @@ -14,7 +14,6 @@ MonoBehaviour: m_Actions: - {fileID: 114000011099735542} - {fileID: 114000011460179744} - - {fileID: 114000010466542208} m_ControlSchemes: - m_Name: MainMenu m_DeviceSlots: @@ -43,38 +42,9 @@ MonoBehaviour: sensitivity: 1000 snap: 1 primaryIsButtonAxis: 0 - - sources: - - controlIndex: 1 - deviceKey: 1 - deadZone: 0.3 - buttonAxisSources: [] - gravity: 1000 - sensitivity: 1000 - snap: 1 - primaryIsButtonAxis: 0 m_MapTypeName: MainMenuInput, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null m_CustomNamespace: ---- !u!114 &114000010466542208 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5eba7b4b2e3ea134991ccbff5f47c2c8, type: 3} - m_Name: BlockY - m_EditorClassIdentifier: - m_ActionMap: {fileID: 11400000} - m_ActionIndex: 2 - m_ControlData: - componentControlIndices: - controlType: - m_TypeName: UnityEngine.InputNew.AxisInputControl, Assembly-CSharp, Version=0.0.0.0, - Culture=neutral, PublicKeyToken=null - name: BlockY - defaultValue: 0 --- !u!114 &114000011099735542 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Menus/MainMenu/MainMenuInput.cs b/Menus/MainMenu/MainMenuInput.cs index 5a9131cf7..7475a7755 100644 --- a/Menus/MainMenu/MainMenuInput.cs +++ b/Menus/MainMenu/MainMenuInput.cs @@ -1,14 +1,13 @@ -using UnityEngine; -using UnityEngine.InputNew; - -// GENERATED FILE - DO NOT EDIT MANUALLY -namespace UnityEngine.InputNew -{ - public class MainMenuInput : ActionMapInput { - public MainMenuInput (ActionMap actionMap) : base (actionMap) { } - - public AxisInputControl @rotate { get { return (AxisInputControl)this[0]; } } - public ButtonInputControl @flickFace { get { return (ButtonInputControl)this[1]; } } - public AxisInputControl @blockY { get { return (AxisInputControl)this[2]; } } - } -} +using UnityEngine; +using UnityEngine.InputNew; + +// GENERATED FILE - DO NOT EDIT MANUALLY +namespace UnityEngine.InputNew +{ + public class MainMenuInput : ActionMapInput { + public MainMenuInput (ActionMap actionMap) : base (actionMap) { } + + public AxisInputControl @rotate { get { return (AxisInputControl)this[0]; } } + public ButtonInputControl @flickFace { get { return (ButtonInputControl)this[1]; } } + } +} diff --git a/Menus/MainMenu/Prefabs/MenuActionButton.prefab b/Menus/MainMenu/Prefabs/MenuActionButton.prefab index 0f98577df..20c7df7cb 100644 --- a/Menus/MainMenu/Prefabs/MenuActionButton.prefab +++ b/Menus/MainMenu/Prefabs/MenuActionButton.prefab @@ -319,9 +319,11 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d6fdf9e0896ac3f4e94809a2cb14ceb8, type: 3} m_Name: m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: f66cb0a158f54124aa4158bbad3ed702, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 114846824440974548} + m_Title: {fileID: 114097649684237516} m_Button: {fileID: 114000011038114608} - m_ButtonDescription: {fileID: 114846824440974548} - m_ButtonTitle: {fileID: 114097649684237516} --- !u!114 &114000012975115684 MonoBehaviour: m_ObjectHideFlags: 1 @@ -727,7 +729,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} m_AnchorMin: {x: 0.20215935, y: -1.0582141} m_AnchorMax: {x: 0.4918094, y: 2.0516362} - m_AnchoredPosition: {x: 0, y: 0.0000038146973} + m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000011878397100 @@ -763,7 +765,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 2.6, y: -0.0024712086} + m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 5.3, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000013226195212 @@ -801,7 +803,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.00008987377, y: 0.006534843} m_AnchorMax: {x: 0.9659295, y: 1} - m_AnchoredPosition: {x: 4.737492, y: 0} + m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 9.475, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000013707443896 diff --git a/Menus/MainMenu/Prefabs/MenuButton.prefab b/Menus/MainMenu/Prefabs/MenuButton.prefab index 307efdadf..ff2a23dad 100644 --- a/Menus/MainMenu/Prefabs/MenuButton.prefab +++ b/Menus/MainMenu/Prefabs/MenuButton.prefab @@ -127,9 +127,11 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d6fdf9e0896ac3f4e94809a2cb14ceb8, type: 3} m_Name: m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: f66cb0a158f54124aa4158bbad3ed702, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 114538117545747488} + m_Title: {fileID: 114736413251300290} m_Button: {fileID: 114000011038114608} - m_ButtonDescription: {fileID: 114538117545747488} - m_ButtonTitle: {fileID: 114736413251300290} --- !u!114 &114000013676702038 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/Menus/MainMenu/Scripts/MainMenuButton.cs b/Menus/MainMenu/Scripts/MainMenuButton.cs index c7ea262a5..0aa04771e 100644 --- a/Menus/MainMenu/Scripts/MainMenuButton.cs +++ b/Menus/MainMenu/Scripts/MainMenuButton.cs @@ -6,30 +6,16 @@ using UnityEngine.EventSystems; using UnityEngine.UI; -#if INCLUDE_TEXT_MESH_PRO -using TMPro; -#endif - [assembly: OptionalDependency("TMPro.TextMeshProUGUI", "INCLUDE_TEXT_MESH_PRO")] namespace UnityEditor.Experimental.EditorVR.Menus { - sealed class MainMenuButton : MonoBehaviour, ITooltip, IRayEnterHandler, IRayExitHandler, IPointerClickHandler + sealed class MainMenuButton : MainMenuSelectable, ITooltip, IRayEnterHandler, IRayExitHandler, IPointerClickHandler { [SerializeField] Button m_Button; -#if INCLUDE_TEXT_MESH_PRO - [SerializeField] - TextMeshProUGUI m_ButtonDescription; -#endif - -#if INCLUDE_TEXT_MESH_PRO - [SerializeField] - TextMeshProUGUI m_ButtonTitle; -#endif - - Color m_OriginalColor; + CanvasGroup m_CanvasGroup; public Button button { get { return m_Button; } } @@ -37,58 +23,52 @@ sealed class MainMenuButton : MonoBehaviour, ITooltip, IRayEnterHandler, IRayExi public ITooltip tooltip { private get; set; } - public Type toolType { get; set; } - - public bool selected - { - set - { - if (value) - { - m_Button.transition = Selectable.Transition.None; - m_Button.targetGraphic.color = m_Button.colors.highlightedColor; - } - else - { - m_Button.transition = Selectable.Transition.ColorTint; - m_Button.targetGraphic.color = m_OriginalColor; - } - } - } - public event Action hovered; public event Action clicked; - void Awake() + new void Awake() { + m_Selectable = m_Button; m_OriginalColor = m_Button.targetGraphic.color; } - public void SetData(string name, string description) + void Start() { -#if INCLUDE_TEXT_MESH_PRO - m_ButtonTitle.text = name; - m_ButtonDescription.text = description; -#endif + m_CanvasGroup = m_Button.GetComponentInParent(); } public void OnRayEnter(RayEventData eventData) { + if (m_CanvasGroup && !m_CanvasGroup.interactable) + return; + #if INCLUDE_TEXT_MESH_PRO - if (hovered != null) - hovered(eventData.rayOrigin, toolType, m_ButtonDescription.text); + if (button.interactable && hovered != null) + { + var descriptionText = string.Empty; + // We can't use ?? because it breaks on destroyed references + if (m_Description) + descriptionText = m_Description.text; + hovered(eventData.rayOrigin, toolType, descriptionText); + } #endif } public void OnRayExit(RayEventData eventData) { - if (hovered != null) + if (m_CanvasGroup && !m_CanvasGroup.interactable) + return; + + if (button.interactable && hovered != null) hovered(eventData.rayOrigin, null, null); } public void OnPointerClick(PointerEventData eventData) { - if (clicked != null) + if (m_CanvasGroup && !m_CanvasGroup.interactable) + return; + + if (button.interactable && clicked != null) clicked(null); // Pass null to perform the selection haptic pulse on both nodes } } diff --git a/Menus/MainMenu/Scripts/MainMenuFace.cs b/Menus/MainMenu/Scripts/MainMenuFace.cs index 171e10fc0..dfd28e3d8 100644 --- a/Menus/MainMenu/Scripts/MainMenuFace.cs +++ b/Menus/MainMenu/Scripts/MainMenuFace.cs @@ -181,7 +181,7 @@ public void AddSubmenu(Transform submenu) visible = false; } - public void RemoveSubmenu() + public void RemoveSubmenu(Transform rayOrigin) { var target = m_Submenus.Pop(); target.SetActive(false); diff --git a/Menus/MainMenu/Scripts/MainMenuSelectable.cs b/Menus/MainMenu/Scripts/MainMenuSelectable.cs new file mode 100644 index 000000000..293f6aa3b --- /dev/null +++ b/Menus/MainMenu/Scripts/MainMenuSelectable.cs @@ -0,0 +1,65 @@ +#if UNITY_EDITOR +using System; +using UnityEditor.Experimental.EditorVR; +using UnityEngine; +using UnityEngine.UI; +using UnityEditor.Experimental.EditorVR.Core; + +#if INCLUDE_TEXT_MESH_PRO +using TMPro; +#endif + +[assembly: OptionalDependency("TMPro.TextMeshProUGUI", "INCLUDE_TEXT_MESH_PRO")] + +namespace UnityEditor.Experimental.EditorVR.Menus +{ + abstract class MainMenuSelectable : MonoBehaviour + { + protected Selectable m_Selectable; + +#if INCLUDE_TEXT_MESH_PRO + [SerializeField] + protected TextMeshProUGUI m_Description; + + [SerializeField] + protected TextMeshProUGUI m_Title; +#endif + + protected Color m_OriginalColor; + + public Type toolType { get; set; } + + public bool selected + { + set + { + if (value) + { + m_Selectable.transition = Selectable.Transition.None; + m_Selectable.targetGraphic.color = m_Selectable.colors.highlightedColor; + } + else + { + m_Selectable.transition = Selectable.Transition.ColorTint; + m_Selectable.targetGraphic.color = m_OriginalColor; + } + } + } + + protected void Awake() + { + m_OriginalColor = m_Selectable.targetGraphic.color; + } + + public void SetData(string name, string description) + { +#if INCLUDE_TEXT_MESH_PRO + m_Title.text = name; + if (m_Description != null) + m_Description.text = description; +#endif + } + } +} +#endif + diff --git a/Menus/MainMenu/Scripts/MainMenuSelectable.cs.meta b/Menus/MainMenu/Scripts/MainMenuSelectable.cs.meta new file mode 100644 index 000000000..3d7f4680b --- /dev/null +++ b/Menus/MainMenu/Scripts/MainMenuSelectable.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: cb860360904848e419f421dbd53b9304 +timeCreated: 1510875372 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/MainMenu/Scripts/MainMenuToggle.cs b/Menus/MainMenu/Scripts/MainMenuToggle.cs new file mode 100644 index 000000000..8c22cba09 --- /dev/null +++ b/Menus/MainMenu/Scripts/MainMenuToggle.cs @@ -0,0 +1,64 @@ +#if UNITY_EDITOR +using System; +using UnityEditor.Experimental.EditorVR; +using UnityEditor.Experimental.EditorVR.Modules; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +[assembly: OptionalDependency("TMPro.TextMeshProUGUI", "INCLUDE_TEXT_MESH_PRO")] + +namespace UnityEditor.Experimental.EditorVR.Menus +{ + sealed class MainMenuToggle : MainMenuSelectable, IRayEnterHandler, IRayExitHandler, IPointerClickHandler + { + [SerializeField] + Toggle m_Toggle; + + CanvasGroup m_CanvasGroup; + + public Toggle toggle { get { return m_Toggle; } } + + public event Action hovered; + public event Action clicked; + + new void Awake() + { + m_Selectable = m_Toggle; + m_OriginalColor = m_Toggle.targetGraphic.color; + } + + void Start() + { + m_CanvasGroup = m_Toggle.GetComponentInParent(); + } + + public void OnRayEnter(RayEventData eventData) + { + if (m_CanvasGroup && !m_CanvasGroup.interactable) + return; + + if (m_Toggle.interactable && hovered != null) + hovered(eventData.rayOrigin); + } + + public void OnRayExit(RayEventData eventData) + { + if (m_CanvasGroup && !m_CanvasGroup.interactable) + return; + + if (m_Toggle.interactable && hovered != null) + hovered(eventData.rayOrigin); + } + + public void OnPointerClick(PointerEventData eventData) + { + if (m_CanvasGroup && !m_CanvasGroup.interactable) + return; + + if (m_Toggle.interactable && clicked != null) + clicked(null); // Pass null to perform the selection haptic pulse on both nodes + } + } +} +#endif diff --git a/Menus/MainMenu/Scripts/MainMenuToggle.cs.meta b/Menus/MainMenu/Scripts/MainMenuToggle.cs.meta new file mode 100644 index 000000000..270dbcaf4 --- /dev/null +++ b/Menus/MainMenu/Scripts/MainMenuToggle.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 766c9196b7801da49b40f523eaa556e6 +timeCreated: 1510876355 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/MainMenu/Scripts/MainMenuUI.cs b/Menus/MainMenu/Scripts/MainMenuUI.cs index 9bc9cf45b..e2e75ffc4 100644 --- a/Menus/MainMenu/Scripts/MainMenuUI.cs +++ b/Menus/MainMenu/Scripts/MainMenuUI.cs @@ -95,6 +95,8 @@ public int targetFaceIndex } } + public bool rotating { get { return m_RotationState != RotationState.AtRest; } } + public Transform menuOrigin { get { return m_MenuOrigin; } diff --git a/Menus/RadialMenu/RadialMenu.cs b/Menus/RadialMenu/RadialMenu.cs index ee5a70c3d..712130639 100644 --- a/Menus/RadialMenu/RadialMenu.cs +++ b/Menus/RadialMenu/RadialMenu.cs @@ -10,7 +10,7 @@ namespace UnityEditor.Experimental.EditorVR.Menus { sealed class RadialMenu : MonoBehaviour, IInstantiateUI, IAlternateMenu, IUsesMenuOrigins, ICustomActionMap, - IControlHaptics, IUsesNode, IConnectInterfaces, IRequestFeedback + IControlHaptics, IUsesNode, IConnectInterfaces, IRequestFeedback, IActionsMenu { const float k_ActivationThreshold = 0.5f; // Do not consume thumbstick or activate menu if the control vector's magnitude is below this threshold @@ -47,6 +47,7 @@ sealed class RadialMenu : MonoBehaviour, IInstantiateUI, IAlternateMenu, IUsesMe public Node node { get; set; } public Bounds localBounds { get { return default(Bounds); } } + public int priority { get { return 1; } } public ActionMap actionMap { get { return m_ActionMap; } } public bool ignoreLocking { get { return false; } } diff --git a/Menus/UndoMenu.meta b/Menus/UndoMenu.meta new file mode 100644 index 000000000..49cadf4f1 --- /dev/null +++ b/Menus/UndoMenu.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 14f060919ebf4764f9c75cc7f2d1bad4 +folderAsset: yes +timeCreated: 1510791326 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/HapticPulses.meta b/Menus/UndoMenu/HapticPulses.meta new file mode 100644 index 000000000..8d883ce22 --- /dev/null +++ b/Menus/UndoMenu/HapticPulses.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 580e3ab5f3b5bb743b9efa689995694d +folderAsset: yes +timeCreated: 1510794417 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/HapticPulses/UndoMenuEngaged.asset b/Menus/UndoMenu/HapticPulses/UndoMenuEngaged.asset new file mode 100644 index 000000000..980b23eb7 --- /dev/null +++ b/Menus/UndoMenu/HapticPulses/UndoMenuEngaged.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1efd705dfe960584581b3390e04777f1, type: 3} + m_Name: UndoMenuEngaged + m_EditorClassIdentifier: + m_Duration: 0.5 + m_Intensity: 0.4 + m_FadeIn: 1 + m_FadeOut: 1 diff --git a/Menus/UndoMenu/HapticPulses/UndoMenuEngaged.asset.meta b/Menus/UndoMenu/HapticPulses/UndoMenuEngaged.asset.meta new file mode 100644 index 000000000..df5b4a6af --- /dev/null +++ b/Menus/UndoMenu/HapticPulses/UndoMenuEngaged.asset.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bd782c338d41a7946959279464013d86 +timeCreated: 1510794425 +licenseType: Pro +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/Materials.meta b/Menus/UndoMenu/Materials.meta new file mode 100644 index 000000000..35d37eca9 --- /dev/null +++ b/Menus/UndoMenu/Materials.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0eed2144b00fdff4faae0b523e7e5e9f +folderAsset: yes +timeCreated: 1510870555 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/Materials/UndoIcon.mat b/Menus/UndoMenu/Materials/UndoIcon.mat new file mode 100644 index 000000000..7cf3668a0 --- /dev/null +++ b/Menus/UndoMenu/Materials/UndoIcon.mat @@ -0,0 +1,77 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: UndoIcon + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: _ALPHABLEND_ON + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 9105 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: f7acf93d805e2dd42b4f32bed5d45ce8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 2 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 5 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Menus/UndoMenu/Materials/UndoIcon.mat.meta b/Menus/UndoMenu/Materials/UndoIcon.mat.meta new file mode 100644 index 000000000..2d56bd2b1 --- /dev/null +++ b/Menus/UndoMenu/Materials/UndoIcon.mat.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e7962268b2f9fa74cb6083e33bb15b9f +timeCreated: 1510869715 +licenseType: Pro +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/Prefabs.meta b/Menus/UndoMenu/Prefabs.meta new file mode 100644 index 000000000..fdab5c1ed --- /dev/null +++ b/Menus/UndoMenu/Prefabs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0ce9ff0bef307ae4b81238959cccbfd7 +folderAsset: yes +timeCreated: 1510792833 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/Prefabs/UndoMenu.prefab b/Menus/UndoMenu/Prefabs/UndoMenu.prefab new file mode 100644 index 000000000..62053559e --- /dev/null +++ b/Menus/UndoMenu/Prefabs/UndoMenu.prefab @@ -0,0 +1,229 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1828616274790540} + m_IsPrefabParent: 1 +--- !u!1 &1695890495350928 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4386191342587820} + - component: {fileID: 33315744622441324} + - component: {fileID: 64453517736190084} + - component: {fileID: 23859873210418424} + m_Layer: 0 + m_Name: Redo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1828616274790540 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4579274395351022} + - component: {fileID: 114635161630974218} + m_Layer: 0 + m_Name: UndoMenu + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1919443148181408 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4809501880196944} + - component: {fileID: 33491512569136768} + - component: {fileID: 64290476127420130} + - component: {fileID: 23850276268091638} + m_Layer: 0 + m_Name: Undo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4386191342587820 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1695890495350928} + m_LocalRotation: {x: 0, y: 0.7071068, z: -0.7071068, w: 0} + m_LocalPosition: {x: 0.01, y: 0, z: 0.00276} + m_LocalScale: {x: 0.017317165, y: -0.01731716, z: 0.01731716} + m_Children: [] + m_Father: {fileID: 4579274395351022} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 90, y: 180, z: 0} +--- !u!4 &4579274395351022 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1828616274790540} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 4809501880196944} + - {fileID: 4386191342587820} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4809501880196944 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1919443148181408} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: -0.01, y: 0, z: 0.00276} + m_LocalScale: {x: 0.017317165, y: 0.01731716, z: 0.01731716} + m_Children: [] + m_Father: {fileID: 4579274395351022} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!23 &23850276268091638 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1919443148181408} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_Materials: + - {fileID: 2100000, guid: e7962268b2f9fa74cb6083e33bb15b9f, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!23 &23859873210418424 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1695890495350928} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_Materials: + - {fileID: 2100000, guid: e7962268b2f9fa74cb6083e33bb15b9f, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &33315744622441324 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1695890495350928} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!33 &33491512569136768 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1919443148181408} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!64 &64290476127420130 +MeshCollider: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1919443148181408} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Convex: 0 + m_CookingOptions: 14 + m_SkinWidth: 0.01 + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!64 &64453517736190084 +MeshCollider: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1695890495350928} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Convex: 0 + m_CookingOptions: 14 + m_SkinWidth: 0.01 + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &114635161630974218 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1828616274790540} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b8ebdbcab31646f4da31c5a9a3f2ce5b, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UndoButtonMeshRenderer: {fileID: 23850276268091638} + m_RedoButtonMeshRenderer: {fileID: 23859873210418424} diff --git a/Menus/UndoMenu/Prefabs/UndoMenu.prefab.meta b/Menus/UndoMenu/Prefabs/UndoMenu.prefab.meta new file mode 100644 index 000000000..20e3ac455 --- /dev/null +++ b/Menus/UndoMenu/Prefabs/UndoMenu.prefab.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ef4e3be7ea1e33b48b3359b2073bb0f3 +timeCreated: 1510792911 +licenseType: Pro +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 100100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/Scripts.meta b/Menus/UndoMenu/Scripts.meta new file mode 100644 index 000000000..a66b09e4a --- /dev/null +++ b/Menus/UndoMenu/Scripts.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: da8416cc900b6a241991c670bc7c3883 +folderAsset: yes +timeCreated: 1510792819 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/Scripts/UndoMenuUI.cs b/Menus/UndoMenu/Scripts/UndoMenuUI.cs new file mode 100644 index 000000000..90892c570 --- /dev/null +++ b/Menus/UndoMenu/Scripts/UndoMenuUI.cs @@ -0,0 +1,149 @@ +#if UNITY_EDITOR +using System.Collections; +using UnityEditor.Experimental.EditorVR.Extensions; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR.Menus +{ + sealed class UndoMenuUI : MonoBehaviour, IConnectInterfaces + { + const float k_EngageAnimationDuration = 0.1f; + const float k_EngagedAlpha = 0.5f; + const float k_DisengagedAlpha = 0.3f; + const float k_UndoPerformedAlpha = 1f; + const string k_MaterialColorProperty = "_Color"; + + [SerializeField] + MeshRenderer m_UndoButtonMeshRenderer; + + [SerializeField] + MeshRenderer m_RedoButtonMeshRenderer; + + Material m_UndoButtonMaterial; + Material m_RedoButtonMaterial; + Coroutine m_EngageCoroutine; + Coroutine m_UndoPerformedCoroutine; + + bool m_Engaged; + bool m_Visible; + + public Transform alternateMenuOrigin + { + get { return m_AlternateMenuOrigin; } + set + { + if (m_AlternateMenuOrigin == value) + return; + + m_AlternateMenuOrigin = value; + transform.SetParent(m_AlternateMenuOrigin); + transform.localPosition = Vector3.zero; + transform.localRotation = Quaternion.identity; + } + } + + Transform m_AlternateMenuOrigin; + + public bool engaged + { + get { return m_Engaged; } + set + { + if (m_Engaged == value) + return; + + m_Engaged = value; + this.RestartCoroutine(ref m_EngageCoroutine, AnimateEngage(m_Engaged)); + } + } + + public bool visible + { + get { return m_Visible; } + set + { + if (m_Visible == value) + return; + + m_Visible = value; + + StopAllCoroutines(); + gameObject.SetActive(value); + } + } + + void Awake() + { + m_UndoButtonMaterial = MaterialUtils.GetMaterialClone(m_UndoButtonMeshRenderer); + m_RedoButtonMaterial = MaterialUtils.GetMaterialClone(m_RedoButtonMeshRenderer); + } + + void OnDestroy() + { + ObjectUtils.Destroy(m_UndoButtonMaterial); + ObjectUtils.Destroy(m_RedoButtonMaterial); + } + + IEnumerator AnimateEngage(bool engaging) + { + var undoStartingColor = m_UndoButtonMaterial.GetColor(k_MaterialColorProperty); + var redoStartingColor = m_RedoButtonMaterial.GetColor(k_MaterialColorProperty); + var targetColor = Color.white; + targetColor.a = engaging ? k_EngagedAlpha : k_DisengagedAlpha; + var transitionAmount = 0f; + var currentDuration = 0f; + while (transitionAmount < 1f) + { + var smoothAmont = MathUtilsExt.SmoothInOutLerpFloat(transitionAmount); + m_UndoButtonMaterial.SetColor(k_MaterialColorProperty, Color.Lerp(undoStartingColor, targetColor, smoothAmont)); + m_RedoButtonMaterial.SetColor(k_MaterialColorProperty, Color.Lerp(redoStartingColor, targetColor, smoothAmont)); + currentDuration += Time.deltaTime; + transitionAmount = currentDuration / k_EngageAnimationDuration; + yield return null; + } + + m_UndoButtonMaterial.SetColor(k_MaterialColorProperty, targetColor); + m_RedoButtonMaterial.SetColor(k_MaterialColorProperty, targetColor); + } + + public void StartPerformedAnimation(bool undo) + { + StopCoroutine(m_EngageCoroutine); + this.RestartCoroutine(ref m_UndoPerformedCoroutine, AnimateUndoPerformed(undo)); + } + + IEnumerator AnimateUndoPerformed(bool undo) + { + var targetMaterial = undo ? m_UndoButtonMaterial : m_RedoButtonMaterial; + var startingColor = m_UndoButtonMaterial.GetColor(k_MaterialColorProperty); + var targetColor = startingColor; + targetColor.a = k_UndoPerformedAlpha; + var transitionAmount = 0f; + var currentDuration = 0f; + while (transitionAmount < 1f) + { + var currentColor = Color.Lerp(startingColor, targetColor, MathUtilsExt.SmoothInOutLerpFloat(transitionAmount)); + targetMaterial.SetColor(k_MaterialColorProperty, currentColor); + currentDuration += Time.deltaTime; + transitionAmount = currentDuration / k_EngageAnimationDuration; + yield return null; + } + + transitionAmount = currentDuration = 0f; + startingColor = targetColor; + targetColor.a = k_DisengagedAlpha; + while (transitionAmount < 1f) + { + var currentColor = Color.Lerp(startingColor, targetColor, MathUtilsExt.SmoothInOutLerpFloat(transitionAmount)); + targetMaterial.SetColor(k_MaterialColorProperty, currentColor); + currentDuration += Time.deltaTime; + transitionAmount = currentDuration / k_EngageAnimationDuration; + yield return null; + } + + targetMaterial.SetColor(k_MaterialColorProperty, targetColor); + } + } +} +#endif diff --git a/Menus/UndoMenu/Scripts/UndoMenuUI.cs.meta b/Menus/UndoMenu/Scripts/UndoMenuUI.cs.meta new file mode 100644 index 000000000..f2e323f09 --- /dev/null +++ b/Menus/UndoMenu/Scripts/UndoMenuUI.cs.meta @@ -0,0 +1,17 @@ +fileFormatVersion: 2 +guid: b8ebdbcab31646f4da31c5a9a3f2ce5b +timeCreated: 1476917998 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: + - m_MissingActionIcon: {fileID: 21300000, guid: 15545907e08dab74692cb3d226382ced, + type: 3} + - m_SlotsMask: {instanceID: 0} + - m_RadialMenuSlotTemplate: {instanceID: 0} + - m_SlotContainer: {instanceID: 0} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/UndoMenu.cs b/Menus/UndoMenu/UndoMenu.cs new file mode 100644 index 000000000..09cd9ae3e --- /dev/null +++ b/Menus/UndoMenu/UndoMenu.cs @@ -0,0 +1,189 @@ +#if UNITY_EDITOR +using System.Collections; +using System.Collections.Generic; +using UnityEditor.Experimental.EditorVR.Core; +using UnityEditor.Experimental.EditorVR.Extensions; +using UnityEditor.Experimental.EditorVR.Proxies; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; +using UnityEngine.InputNew; + +namespace UnityEditor.Experimental.EditorVR.Menus +{ + sealed class UndoMenu : MonoBehaviour, IInstantiateUI, IUsesMenuOrigins, ICustomActionMap, + IControlHaptics, IUsesNode, IConnectInterfaces, IRequestFeedback, IUsesDeviceType, IAlternateMenu + { + const float k_UndoRedoThreshold = 0.5f; + const string k_EngageControlName = "Engage"; + const float k_EngageUndoAfterStickReleasedDuration = 0.1f; // Duration after releasing the joystick to still accept a left/right flick to undo/redo. + const string k_FeedbackHintForJoystickController = "Click + flick left/right to undo/redo"; + const string k_FeedbackHintForTrackpadController = "Click left/right side to undo/redo"; + + [SerializeField] + ActionMap m_ActionMap; + + [SerializeField] + UndoMenuUI m_UndoMenuPrefab; + + [SerializeField] + HapticPulse m_UndoPulse; + + UndoMenuUI m_UndoMenuUI; + Transform m_AlternateMenuOrigin; + MenuHideFlags m_MenuHideFlags = MenuHideFlags.Hidden; + float m_PrevNavigateX; + bool m_StillEngagedAfterStickRelease; + Coroutine m_StillEngagedAfterStickReleasedCoroutine; + bool m_TrackpadController; + string m_FeedbackHintForCurrentController; + + readonly BindingDictionary m_Controls = new BindingDictionary(); + + public Transform menuOrigin { get; set; } + public Transform rayOrigin { get; set; } + public Node node { get; set; } + + public GameObject menuContent { get { return m_UndoMenuUI.gameObject; } } + public Bounds localBounds { get { return default(Bounds); } } + public int priority { get { return 0; } } + public ActionMap actionMap { get { return m_ActionMap; } } + public bool ignoreLocking { get { return false; } } + + public Transform alternateMenuOrigin + { + get { return m_AlternateMenuOrigin; } + set + { + m_AlternateMenuOrigin = value; + + if (m_UndoMenuUI != null) + m_UndoMenuUI.alternateMenuOrigin = value; + } + } + + public MenuHideFlags menuHideFlags + { + get { return m_MenuHideFlags; } + set + { + if (m_MenuHideFlags != value) + { + m_MenuHideFlags = value; + + var visible = value == 0; + if (m_UndoMenuUI) + m_UndoMenuUI.visible = visible; + + if (visible) + ShowFeedback(); + } + } + } + + void Start() + { + m_UndoMenuUI = this.InstantiateUI(m_UndoMenuPrefab.gameObject).GetComponent(); + m_UndoMenuUI.alternateMenuOrigin = alternateMenuOrigin; + this.ConnectInterfaces(m_UndoMenuUI); // Connect interfaces before performing setup on the UI + m_UndoMenuUI.gameObject.SetActive(false); + InputUtils.GetBindingDictionaryFromActionMap(m_ActionMap, m_Controls); + m_TrackpadController = this.GetDeviceType() == DeviceType.Vive; + m_FeedbackHintForCurrentController = m_TrackpadController + ? k_FeedbackHintForTrackpadController + : k_FeedbackHintForJoystickController; + } + + public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeControl) + { + if (!m_UndoMenuUI.visible) + return; + + var undoMenuInput = (UndoMenuInput)input; + if (undoMenuInput == null) + { + this.ClearFeedbackRequests(); + return; + } + + var engage = undoMenuInput.engage; + if (engage.wasJustReleased && !m_TrackpadController) + this.RestartCoroutine(ref m_StillEngagedAfterStickReleasedCoroutine, AcceptInputAfterStickReleased()); + + if (!(engage.wasJustPressed || !m_TrackpadController && (engage.isHeld || m_StillEngagedAfterStickRelease))) + return; + + consumeControl(engage); + m_UndoMenuUI.engaged = true; + + var navigateXControl = undoMenuInput.navigateX; + var navigateX = navigateXControl.value; + var undoRedoPerformed = false; + if (navigateX < -k_UndoRedoThreshold && (m_TrackpadController || m_PrevNavigateX > -k_UndoRedoThreshold)) + { + Undo.PerformUndo(); + m_UndoMenuUI.StartPerformedAnimation(true); + ShowUndoPerformedFeedback(true); + undoRedoPerformed = true; + } + else if (navigateX > k_UndoRedoThreshold && (m_TrackpadController || m_PrevNavigateX < k_UndoRedoThreshold)) + { + Undo.PerformRedo(); + m_UndoMenuUI.StartPerformedAnimation(false); + ShowUndoPerformedFeedback(false); + undoRedoPerformed = true; + } + + m_PrevNavigateX = navigateX; + + if (undoRedoPerformed) + { + consumeControl(navigateXControl); + this.StopCoroutine(ref m_StillEngagedAfterStickReleasedCoroutine); + this.Pulse(node, m_UndoPulse); + } + } + + IEnumerator AcceptInputAfterStickReleased() + { + m_StillEngagedAfterStickRelease = true; + yield return new WaitForSeconds(k_EngageUndoAfterStickReleasedDuration); + m_StillEngagedAfterStickRelease = false; + m_UndoMenuUI.engaged = false; + } + + void ShowFeedback() + { + List controls; + if (m_Controls.TryGetValue(k_EngageControlName, out controls)) + { + foreach (var id in controls) + { + this.AddFeedbackRequest(new ProxyFeedbackRequest + { + control = id, + node = node, + tooltipText = m_FeedbackHintForCurrentController + }); + } + } + } + + void ShowUndoPerformedFeedback(bool undo) + { + List controls; + if (m_Controls.TryGetValue(k_EngageControlName, out controls)) + { + foreach (var id in controls) + { + this.AddFeedbackRequest(new ProxyFeedbackRequest + { + control = id, + node = node, + tooltipText = string.Format("{0} performed", undo ? "Undo" : "Redo") + }); + } + } + } + } +} +#endif diff --git a/Menus/UndoMenu/UndoMenu.cs.meta b/Menus/UndoMenu/UndoMenu.cs.meta new file mode 100644 index 000000000..b4e756efd --- /dev/null +++ b/Menus/UndoMenu/UndoMenu.cs.meta @@ -0,0 +1,17 @@ +fileFormatVersion: 2 +guid: c99359ddbc777c54b8bbcb77f816dec5 +timeCreated: 1510794469 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: + - m_ActionMap: {fileID: 11400000, guid: cda0a686e569b574b97504a76b497815, type: 2} + - m_UndoMenuPrefab: {fileID: 114635161630974218, guid: ef4e3be7ea1e33b48b3359b2073bb0f3, + type: 2} + - m_UndoPulse: {fileID: 11400000, guid: bd782c338d41a7946959279464013d86, type: 2} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/UndoMenuInput.asset b/Menus/UndoMenu/UndoMenuInput.asset new file mode 100644 index 000000000..aa56ff8f3 --- /dev/null +++ b/Menus/UndoMenu/UndoMenuInput.asset @@ -0,0 +1,87 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 24e5bc088c9caeb44bc4283dc321b033, type: 3} + m_Name: UndoMenuInput + m_EditorClassIdentifier: + m_Actions: + - {fileID: 114324171257110392} + - {fileID: 114746503017599090} + m_ControlSchemes: + - m_Name: UndoMenu + m_DeviceSlots: + - m_Key: 1 + m_Type: + m_TypeName: UnityEngine.InputNew.VRInputDevice, Assembly-CSharp, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null + m_TagIndex: -1 + m_ActionMap: {fileID: 11400000} + m_Bindings: + - sources: + - controlIndex: 0 + deviceKey: 1 + deadZone: 0.3 + buttonAxisSources: [] + gravity: 1000 + sensitivity: 1000 + snap: 1 + primaryIsButtonAxis: 0 + - sources: + - controlIndex: 22 + deviceKey: 1 + deadZone: 0.3 + buttonAxisSources: [] + gravity: 1000 + sensitivity: 1000 + snap: 1 + primaryIsButtonAxis: 0 + m_MapTypeName: UndoMenuInput, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, + PublicKeyToken=null + m_CustomNamespace: +--- !u!114 &114324171257110392 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5eba7b4b2e3ea134991ccbff5f47c2c8, type: 3} + m_Name: NavigateX + m_EditorClassIdentifier: + m_ActionMap: {fileID: 11400000} + m_ActionIndex: 0 + m_ControlData: + componentControlIndices: + controlType: + m_TypeName: UnityEngine.InputNew.AxisInputControl, Assembly-CSharp, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null + name: NavigateX + defaultValue: 0 +--- !u!114 &114746503017599090 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5eba7b4b2e3ea134991ccbff5f47c2c8, type: 3} + m_Name: Engage + m_EditorClassIdentifier: + m_ActionMap: {fileID: 11400000} + m_ActionIndex: 1 + m_ControlData: + componentControlIndices: + controlType: + m_TypeName: UnityEngine.InputNew.ButtonInputControl, Assembly-CSharp, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null + name: Engage + defaultValue: 0 diff --git a/Menus/UndoMenu/UndoMenuInput.asset.meta b/Menus/UndoMenu/UndoMenuInput.asset.meta new file mode 100644 index 000000000..decfc3487 --- /dev/null +++ b/Menus/UndoMenu/UndoMenuInput.asset.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cda0a686e569b574b97504a76b497815 +timeCreated: 1510792084 +licenseType: Pro +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Menus/UndoMenu/UndoMenuInput.cs b/Menus/UndoMenu/UndoMenuInput.cs new file mode 100644 index 000000000..801474f0f --- /dev/null +++ b/Menus/UndoMenu/UndoMenuInput.cs @@ -0,0 +1,13 @@ +using UnityEngine; +using UnityEngine.InputNew; + +// GENERATED FILE - DO NOT EDIT MANUALLY +namespace UnityEngine.InputNew +{ + public class UndoMenuInput : ActionMapInput { + public UndoMenuInput (ActionMap actionMap) : base (actionMap) { } + + public AxisInputControl @navigateX { get { return (AxisInputControl)this[0]; } } + public ButtonInputControl @engage { get { return (ButtonInputControl)this[1]; } } + } +} diff --git a/Menus/UndoMenu/UndoMenuInput.cs.meta b/Menus/UndoMenu/UndoMenuInput.cs.meta new file mode 100644 index 000000000..f74916f28 --- /dev/null +++ b/Menus/UndoMenu/UndoMenuInput.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 8d787422bd98e624aa130c05c11e85b6 +timeCreated: 1510792094 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Models/Vive/Materials/ViveController.mat b/Models/Vive/Materials/ViveController.mat index d1e045a5a..3b37e57d2 100644 --- a/Models/Vive/Materials/ViveController.mat +++ b/Models/Vive/Materials/ViveController.mat @@ -75,7 +75,7 @@ Material: - _SpecularHighlights: 1 - _SrcBlend: 5 - _UVSec: 0 - - _ZWrite: 0 + - _ZWrite: 1 m_Colors: - _Color: {r: 1, g: 1, b: 1, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Scripts/Actions/ActionMenuItemAttribute.cs b/Scripts/Actions/ActionMenuItemAttribute.cs index 2641a294f..e1f0f401b 100644 --- a/Scripts/Actions/ActionMenuItemAttribute.cs +++ b/Scripts/Actions/ActionMenuItemAttribute.cs @@ -1,33 +1,33 @@ -#if UNITY_EDITOR -namespace UnityEditor.Experimental.EditorVR -{ - /// - /// Attribute used to tag Action classes in order to be added to VR menus - /// - public class ActionMenuItemAttribute : System.Attribute, ITooltip - { - internal const string DefaultActionSectionName = "DefaultActions"; - internal string name; - internal string sectionName; - internal int priority; - - /// - /// The tooltip string - /// - public string tooltipText { get { return name; } } - - /// - /// Constructor - /// - /// The name of this action - /// The name of the section in which this action should reside - /// The ordinal of this action within the section it resides - public ActionMenuItemAttribute(string name, string sectionName = null, int priority = int.MaxValue) - { - this.name = name; - this.sectionName = sectionName; - this.priority = priority; - } - } -} -#endif +#if UNITY_EDITOR +namespace UnityEditor.Experimental.EditorVR +{ + /// + /// Attribute used to tag Action classes in order to be added to VR menus + /// + public class ActionMenuItemAttribute : System.Attribute, ITooltip + { + internal const string DefaultActionSectionName = "DefaultActions"; + internal string name; + internal string sectionName; + internal int priority; + + /// + /// The tooltip string + /// + public string tooltipText { get { return name; } } + + /// + /// Constructor + /// + /// The name of this action + /// The name of the section in which this action should reside + /// The ordinal of this action within the section it resides + public ActionMenuItemAttribute(string name, string sectionName = null, int priority = int.MaxValue) + { + this.name = name; + this.sectionName = sectionName; + this.priority = priority; + } + } +} +#endif diff --git a/Scripts/Core/Contexts/EditingContextManager.cs b/Scripts/Core/Contexts/EditingContextManager.cs index 371bdecd9..efd5fa17d 100644 --- a/Scripts/Core/Contexts/EditingContextManager.cs +++ b/Scripts/Core/Contexts/EditingContextManager.cs @@ -22,28 +22,32 @@ sealed class EditingContextManager : MonoBehaviour const string k_LaunchOnExitPlaymode = "EditingContextManager.LaunchOnExitPlaymode"; + IEditingContext m_CurrentContext; + internal static EditingContextManager s_Instance; static InputManager s_InputManager; + static List s_AvailableContexts; + static EditingContextManagerSettings s_Settings; + static UnityObject s_DefaultContext; - EditingContextManagerSettings m_Settings = null; - - List m_AvailableContexts; - string[] m_ContextNames = null; + string[] m_ContextNames; int m_SelectedContextIndex; - IEditingContext m_CurrentContext; + Rect m_EditingContextPopupRect = new Rect(0, 0, 150, 20); // Y and X position will be set based on window size + readonly List m_PreviousContexts = new List(); - internal IEditingContext defaultContext + internal static IEditingContext defaultContext { get { - var context = m_AvailableContexts.Find(c => c.Equals(m_DefaultContext)) ?? m_AvailableContexts.First(); + var availableContexts = GetAvailableEditingContexts(); + var context = availableContexts.Find(c => c.Equals(s_DefaultContext)) ?? availableContexts.First(); - var defaultContextName = m_Settings.defaultContextName; + var defaultContextName = settings.defaultContextName; if (!string.IsNullOrEmpty(defaultContextName)) { - var foundContext = m_AvailableContexts.Find(c => c.name == defaultContextName); + var foundContext = availableContexts.Find(c => c.name == defaultContextName); if (foundContext != null) context = foundContext; } @@ -52,7 +56,7 @@ internal IEditingContext defaultContext } set { - m_Settings.defaultContextName = value.name; + settings.defaultContextName = value.name; } } @@ -61,6 +65,17 @@ internal IEditingContext currentContext get { return m_CurrentContext; } } + static EditingContextManagerSettings settings + { + get + { + if (!s_Settings) + s_Settings = LoadUserSettings(); + + return s_Settings; + } + } + static EditingContextManager() { VRView.viewEnabled += OnVRViewEnabled; @@ -131,29 +146,18 @@ static void OnPlayModeStateChanged(PlayModeStateChange stateChange) void OnEnable() { - m_Settings = LoadUserSettings(); - ISetEditingContextMethods.getAvailableEditingContexts = GetAvailableEditingContexts; ISetEditingContextMethods.getPreviousEditingContexts = GetPreviousEditingContexts; ISetEditingContextMethods.setEditingContext = SetEditingContext; ISetEditingContextMethods.restorePreviousEditingContext = RestorePreviousContext; - var availableContexts = GetAvailableEditingContexts(); - m_ContextNames = availableContexts.Select(c => c.name).ToArray(); - - if (m_AvailableContexts.Count == 0) - throw new Exception("You can't start EditorXR without at least one context. Try re-importing the package or use version control to restore the default context asset"); - - SetEditingContext(defaultContext); - - if (m_AvailableContexts.Count > 1) - VRView.afterOnGUI += OnVRViewGUI; - // Force the window to repaint every tick, since we need live updating // This also allows scripts with [ExecuteInEditMode] to run EditorApplication.update += EditorApplication.QueuePlayerLoopUpdate; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; + + SetEditingContext(defaultContext); } void OnDisable() @@ -170,40 +174,44 @@ void OnDisable() m_CurrentContext.Dispose(); } - m_AvailableContexts = null; + s_AvailableContexts = null; + + SetEditingContext(null); ISetEditingContextMethods.getAvailableEditingContexts = null; ISetEditingContextMethods.getPreviousEditingContexts = null; ISetEditingContextMethods.setEditingContext = null; ISetEditingContextMethods.restorePreviousEditingContext = null; - SaveUserSettings(m_Settings); + SaveUserSettings(settings); } #endif - void OnVRViewGUI(EditorWindow window) + + void Awake() { - var view = (VRView)window; - GUILayout.BeginArea(view.guiRect); - { - GUILayout.FlexibleSpace(); - GUILayout.BeginHorizontal(); - { - DoGUI(m_ContextNames, ref m_SelectedContextIndex, () => SetEditingContext(m_AvailableContexts[m_SelectedContextIndex])); - GUILayout.FlexibleSpace(); - } - GUILayout.EndHorizontal(); - } - GUILayout.EndArea(); + s_DefaultContext = m_DefaultContext; + + var availableContexts = GetAvailableEditingContexts(); + m_ContextNames = availableContexts.Select(c => c.name).ToArray(); + + if (s_AvailableContexts.Count == 0) + throw new Exception("You can't start EditorXR without at least one context. Try re-importing the package or use version control to restore the default context asset"); + + if (s_AvailableContexts.Count > 1) + VRView.afterOnGUI += OnVRViewGUI; } - internal static void DoGUI(string[] contextNames, ref int selectedContextIndex, Action callback = null) + void OnVRViewGUI(VRView view) { - selectedContextIndex = EditorGUILayout.Popup(string.Empty, selectedContextIndex, contextNames); + var position = view.position; + m_EditingContextPopupRect.y = position.height - m_EditingContextPopupRect.height; + m_EditingContextPopupRect.x = position.width - m_EditingContextPopupRect.width; + + m_SelectedContextIndex = EditorGUI.Popup(m_EditingContextPopupRect, string.Empty, m_SelectedContextIndex, m_ContextNames); if (GUI.changed) { - if (callback != null) - callback(); + SetEditingContext(s_AvailableContexts[m_SelectedContextIndex]); GUIUtility.ExitGUI(); } } @@ -216,13 +224,15 @@ internal void SetEditingContext(IEditingContext context) if (m_CurrentContext != null) { m_PreviousContexts.Insert(0, m_CurrentContext); - m_CurrentContext.Dispose(); + + if (m_CurrentContext.instanceExists) + m_CurrentContext.Dispose(); } context.Setup(); m_CurrentContext = context; - m_SelectedContextIndex = m_AvailableContexts.IndexOf(context); + m_SelectedContextIndex = s_AvailableContexts.IndexOf(context); } internal void RestorePreviousContext() @@ -254,12 +264,12 @@ internal static string[] GetEditingContextNames() return availableContexts.Select(c => c.name).ToArray(); } - List GetAvailableEditingContexts() + static List GetAvailableEditingContexts() { - if (m_AvailableContexts == null) - m_AvailableContexts = GetEditingContextAssets(); + if (s_AvailableContexts == null) + s_AvailableContexts = GetEditingContextAssets(); - return m_AvailableContexts; + return s_AvailableContexts; } List GetPreviousEditingContexts() diff --git a/Scripts/Core/Contexts/EditorVR.asset b/Scripts/Core/Contexts/EditorVR.asset index a1f03787d..05fd7141c 100644 --- a/Scripts/Core/Contexts/EditorVR.asset +++ b/Scripts/Core/Contexts/EditorVR.asset @@ -12,6 +12,7 @@ MonoBehaviour: m_Name: EditorVR m_EditorClassIdentifier: m_RenderScale: 1 + m_CopySceneCameraSettings: 1 m_DefaultToolStack: - {fileID: 11500000, guid: 882053426a5f76d46b5505d9a20be912, type: 3} - {fileID: 11500000, guid: aab8fcc587f237c4cb48fb7bc8a59909, type: 3} diff --git a/Scripts/Core/Contexts/EditorVRContext.cs b/Scripts/Core/Contexts/EditorVRContext.cs index ca62916e0..813e6027c 100644 --- a/Scripts/Core/Contexts/EditorVRContext.cs +++ b/Scripts/Core/Contexts/EditorVRContext.cs @@ -13,16 +13,22 @@ class EditorVRContext : ScriptableObject, IEditingContext [SerializeField] float m_RenderScale = 1f; + [SerializeField] + bool m_CopyExistingCameraSettings = true; + [SerializeField] internal List m_DefaultToolStack; EditorVR m_Instance; + public bool copyExistingCameraSettings { get { return m_CopyExistingCameraSettings; } } + + public bool instanceExists { get { return m_Instance != null; } } + public void Setup() { EditorVR.defaultTools = m_DefaultToolStack.Select(ms => ms.GetClass()).ToArray(); m_Instance = ObjectUtils.CreateGameObjectWithComponent(); - XRSettings.eyeTextureResolutionScale = m_RenderScale; } diff --git a/Scripts/Core/EditorVR.Menus.cs b/Scripts/Core/EditorVR.Menus.cs index 664302b5b..d00b1cc3a 100644 --- a/Scripts/Core/EditorVR.Menus.cs +++ b/Scripts/Core/EditorVR.Menus.cs @@ -1,587 +1,607 @@ -#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor.Experimental.EditorVR.Menus; -using UnityEditor.Experimental.EditorVR.Modules; -using UnityEditor.Experimental.EditorVR.UI; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; - -namespace UnityEditor.Experimental.EditorVR.Core -{ - partial class EditorVR - { - const float k_MainMenuAutoHideDelay = 0.125f; - const float k_MainMenuAutoShowDelay = 0.25f; - - class Menus : Nested, IInterfaceConnector, ILateBindInterfaceMethods, IConnectInterfaces - { - internal class MenuHideData - { - public MenuHideFlags hideFlags = MenuHideFlags.Hidden; - public MenuHideFlags lastHideFlags = MenuHideFlags.Hidden; - public float autoHideTime; - public float autoShowTime; - } - - const float k_MenuHideMargin = 0.075f; - const float k_TwoHandHideDistance = 0.25f; - const int k_PossibleOverlaps = 16; - - readonly Dictionary m_MainMenus = new Dictionary(); - readonly Dictionary, ISettingsMenuProvider> m_SettingsMenuProviders = new Dictionary, ISettingsMenuProvider>(); - readonly Dictionary, ISettingsMenuItemProvider> m_SettingsMenuItemProviders = new Dictionary, ISettingsMenuItemProvider>(); - List m_MainMenuTools; - - // Local method use only -- created here to reduce garbage collection - static readonly List k_ActiveDeviceData = new List(); - static readonly List k_WorkspaceComponents = new List(); - static readonly List k_ButtonComponents = new List(); - static readonly Collider[] k_ColliderOverlaps = new Collider[k_PossibleOverlaps]; - - public Menus() - { - IInstantiateMenuUIMethods.instantiateMenuUI = InstantiateMenuUI; - IIsMainMenuVisibleMethods.isMainMenuVisible = IsMainMenuVisible; - IUsesCustomMenuOriginsMethods.getCustomMenuOrigin = GetCustomMenuOrigin; - IUsesCustomMenuOriginsMethods.getCustomAlternateMenuOrigin = GetCustomAlternateMenuOrigin; - } - - public void ConnectInterface(object target, object userData = null) - { - var rayOrigin = userData as Transform; - var settingsMenuProvider = target as ISettingsMenuProvider; - if (settingsMenuProvider != null) - { - m_SettingsMenuProviders[new KeyValuePair(target.GetType(), rayOrigin)] = settingsMenuProvider; - foreach (var kvp in m_MainMenus) - { - if (rayOrigin == null || kvp.Key == rayOrigin) - kvp.Value.AddSettingsMenu(settingsMenuProvider); - } - } - - var settingsMenuItemProvider = target as ISettingsMenuItemProvider; - if (settingsMenuItemProvider != null) - { - m_SettingsMenuItemProviders[new KeyValuePair(target.GetType(), rayOrigin)] = settingsMenuItemProvider; - foreach (var kvp in m_MainMenus) - { - if (rayOrigin == null || kvp.Key == rayOrigin) - kvp.Value.AddSettingsMenuItem(settingsMenuItemProvider); - } - } - - var mainMenu = target as IMainMenu; - if (mainMenu != null && rayOrigin != null) - { - mainMenu.menuTools = m_MainMenuTools; - mainMenu.menuWorkspaces = WorkspaceModule.workspaceTypes; - mainMenu.settingsMenuProviders = m_SettingsMenuProviders; - mainMenu.settingsMenuItemProviders = m_SettingsMenuItemProviders; - m_MainMenus[rayOrigin] = mainMenu; - } - - var menuOrigins = target as IUsesMenuOrigins; - if (menuOrigins != null) - { - Transform mainMenuOrigin; - var proxy = Rays.GetProxyForRayOrigin(rayOrigin); - if (proxy != null && proxy.menuOrigins.TryGetValue(rayOrigin, out mainMenuOrigin)) - { - menuOrigins.menuOrigin = mainMenuOrigin; - Transform alternateMenuOrigin; - if (proxy.alternateMenuOrigins.TryGetValue(rayOrigin, out alternateMenuOrigin)) - menuOrigins.alternateMenuOrigin = alternateMenuOrigin; - } - } - } - - public void DisconnectInterface(object target, object userData = null) - { - var rayOrigin = userData as Transform; - var settingsMenuProvider = target as ISettingsMenuProvider; - if (settingsMenuProvider != null) - { - foreach (var kvp in m_MainMenus) - { - if (rayOrigin == null || kvp.Key == rayOrigin) - kvp.Value.RemoveSettingsMenu(settingsMenuProvider); - } - - m_SettingsMenuProviders.Remove(new KeyValuePair(target.GetType(), rayOrigin)); - } - - var settingsMenuItemProvider = target as ISettingsMenuItemProvider; - if (settingsMenuItemProvider != null) - { - foreach (var kvp in m_MainMenus) - { - if (rayOrigin == null || kvp.Key == rayOrigin) - kvp.Value.RemoveSettingsMenuItem(settingsMenuItemProvider); - } - - m_SettingsMenuItemProviders.Remove(new KeyValuePair(target.GetType(), rayOrigin)); - } - - var mainMenu = target as IMainMenu; - if (mainMenu != null && rayOrigin != null) - m_MainMenus.Remove(rayOrigin); - } - - public void LateBindInterfaceMethods(Tools provider) - { - m_MainMenuTools = provider.allTools.Where(t => !Tools.IsDefaultTool(t)).ToList(); // Don't show tools that can't be selected/toggled - } - - static void UpdateAlternateMenuForDevice(DeviceData deviceData) - { - var alternateMenu = deviceData.alternateMenu; - alternateMenu.menuHideFlags = deviceData.currentTool is IExclusiveMode ? 0 : deviceData.menuHideData[alternateMenu].hideFlags; - - // Move the Tools Menu buttons to an alternate position if the alternate menu will be shown - deviceData.toolsMenu.alternateMenuVisible = alternateMenu.menuHideFlags == 0; - } - - static Transform GetCustomMenuOrigin(Transform rayOrigin) - { - Transform mainMenuOrigin = null; - - var proxy = Rays.GetProxyForRayOrigin(rayOrigin); - if (proxy != null) - { - var menuOrigins = proxy.menuOrigins; - if (menuOrigins.ContainsKey(rayOrigin)) - mainMenuOrigin = menuOrigins[rayOrigin]; - } - - return mainMenuOrigin; - } - - static Transform GetCustomAlternateMenuOrigin(Transform rayOrigin) - { - Transform alternateMenuOrigin = null; - - var proxy = Rays.GetProxyForRayOrigin(rayOrigin); - if (proxy != null) - { - var alternateMenuOrigins = proxy.alternateMenuOrigins; - if (alternateMenuOrigins.ContainsKey(rayOrigin)) - alternateMenuOrigin = alternateMenuOrigins[rayOrigin]; - } - - return alternateMenuOrigin; - } - - internal void UpdateMenuVisibilities() - { - k_ActiveDeviceData.Clear(); - Rays.ForEachProxyDevice(deviceData => { k_ActiveDeviceData.Add(deviceData); }); - - foreach (var deviceData in k_ActiveDeviceData) - { - foreach (var kvp in deviceData.menuHideData) - { - kvp.Value.hideFlags &= ~MenuHideFlags.Temporary; - } - } - - foreach (var deviceData in k_ActiveDeviceData) - { - var alternateMenu = deviceData.alternateMenu; - var mainMenu = deviceData.mainMenu; - var customMenu = deviceData.customMenu; - var menuHideData = deviceData.menuHideData; - MenuHideData customMenuHideData = null; - MenuHideData alternateMenuData = null; - - var mainMenuVisible = mainMenu != null && menuHideData[mainMenu].hideFlags == 0; - var mainMenuSupressed = mainMenu != null && ((menuHideData[mainMenu].hideFlags & MenuHideFlags.Occluded) != 0); - - var alternateMenuVisible = false; - if (alternateMenu != null) - { - alternateMenuData = menuHideData[alternateMenu]; - alternateMenuVisible = alternateMenuData.hideFlags == 0; - } - - var customMenuVisible = false; - if (customMenu != null) - { - customMenuHideData = menuHideData[customMenu]; - customMenuVisible = customMenuHideData.hideFlags == 0; - } - - // Kick the alternate menu to the other hand if a main menu or custom menu is visible - if (alternateMenuVisible && (mainMenuVisible || customMenuVisible)) - { - foreach (var otherDeviceData in k_ActiveDeviceData) - { - if (otherDeviceData == deviceData) - continue; - - SetAlternateMenuVisibility(otherDeviceData.rayOrigin, true); - break; - } - } - - // Temporarily hide customMenu if other menus are visible or should be - if (customMenuVisible && (mainMenuVisible || mainMenuSupressed)) - customMenuHideData.hideFlags |= MenuHideFlags.OtherMenu; - - // Temporarily hide alternateMenu if other menus are visible - if (alternateMenuVisible && (customMenuVisible || mainMenuVisible)) - alternateMenuData.hideFlags |= MenuHideFlags.OtherMenu; - - // Check if menu bounds overlap with any workspace colliders - foreach (var kvp in menuHideData) - { - CheckMenuColliderOverlaps(kvp.Key, kvp.Value); - } - - // Check if there are currently any held objects, or if the other hand is in proximity for scaling - CheckDirectSelection(deviceData, menuHideData, alternateMenuVisible); - } - - // Set show/hide timings - foreach (var deviceData in k_ActiveDeviceData) - { - foreach (var kvp in deviceData.menuHideData) - { - var hideFlags = kvp.Value.hideFlags; - if ((hideFlags & ~MenuHideFlags.Hidden & ~MenuHideFlags.OtherMenu) == 0) - kvp.Value.autoHideTime = Time.time; - - if (hideFlags != 0) - { - var menuHideData = kvp.Value; - menuHideData.lastHideFlags = menuHideData.hideFlags; - kvp.Value.autoShowTime = Time.time; - } - } - } - - // Apply MenuHideFlags to UI visibility - foreach (var deviceData in k_ActiveDeviceData) - { - var mainMenu = deviceData.mainMenu; - var mainMenuHideData = deviceData.menuHideData[mainMenu]; - var mainMenuHideFlags = mainMenuHideData.hideFlags; - var lastMainMenuHideFlags = mainMenuHideData.lastHideFlags; - - var permanentlyHidden = (mainMenuHideFlags & MenuHideFlags.Hidden) != 0; - var wasPermanentlyHidden = (lastMainMenuHideFlags & MenuHideFlags.Hidden) != 0; - - //Temporary states take effect after a delay - var temporarilyHidden = (mainMenuHideFlags & MenuHideFlags.Temporary) != 0 - && Time.time > mainMenuHideData.autoHideTime + k_MainMenuAutoHideDelay; - var wasTemporarilyHidden = (lastMainMenuHideFlags & MenuHideFlags.Temporary) != 0 - && Time.time > mainMenuHideData.autoShowTime + k_MainMenuAutoShowDelay; - - // If the menu is focused, only hide if Hidden is set (e.g. not temporary) in order to hide the selected tool - if (permanentlyHidden || wasPermanentlyHidden || !mainMenu.focus && (temporarilyHidden || wasTemporarilyHidden)) - mainMenu.menuHideFlags = mainMenuHideFlags; - - // Disable the main menu activator if any temporary states are set - deviceData.toolsMenu.mainMenuActivatorInteractable = (mainMenuHideFlags & MenuHideFlags.Temporary) == 0; - - // Show/hide custom menu, if it exists - var customMenu = deviceData.customMenu; - if (customMenu != null) - customMenu.menuHideFlags = deviceData.menuHideData[customMenu].hideFlags; - - UpdateAlternateMenuForDevice(deviceData); - Rays.UpdateRayForDevice(deviceData, deviceData.rayOrigin); - } - - evr.GetModule().UpdatePlayerHandleMaps(); - } - - void CheckDirectSelection(DeviceData deviceData, Dictionary menuHideData, bool alternateMenuVisible) - { - var viewerScale = Viewer.GetViewerScale(); - var directSelection = evr.GetNestedModule(); - var rayOrigin = deviceData.rayOrigin; - var rayOriginPosition = rayOrigin.position; - var heldObjects = directSelection.GetHeldObjects(rayOrigin); - - // If this hand is holding any objects, hide its menus - var hasDirectSelection = heldObjects != null && heldObjects.Count > 0; - if (hasDirectSelection) - { - foreach (var kvp in menuHideData) - { - // Only set if hidden--value is reset every frame - kvp.Value.hideFlags |= MenuHideFlags.HasDirectSelection; - } - - foreach (var otherDeviceData in k_ActiveDeviceData) - { - if (otherDeviceData == deviceData) - continue; - - var otherRayOrigin = otherDeviceData.rayOrigin; - if (alternateMenuVisible && otherDeviceData.alternateMenu != null) - SetAlternateMenuVisibility(otherRayOrigin, true); - - // If other hand is within range to do a two-handed scale, hide its menu as well - if (directSelection.IsHovering(otherRayOrigin) || directSelection.IsScaling(otherRayOrigin) - || Vector3.Distance(otherRayOrigin.position, rayOriginPosition) < k_TwoHandHideDistance * viewerScale) - { - foreach (var kvp in otherDeviceData.menuHideData) - { - // Only set if hidden--value is reset every frame - kvp.Value.hideFlags |= MenuHideFlags.HasDirectSelection; - } - break; - } - } - } - } - - void CheckMenuColliderOverlaps(IMenu menu, MenuHideData menuHideData) - { - var menuBounds = menu.localBounds; - if (menuBounds.extents == Vector3.zero) - return; - - Array.Clear(k_ColliderOverlaps, 0, k_ColliderOverlaps.Length); - var hoveringCollider = false; - var menuTransform = menu.menuContent.transform; - var menuRotation = menuTransform.rotation; - var viewerScale = Viewer.GetViewerScale(); - var center = menuTransform.position + menuRotation * menuBounds.center * viewerScale; - if (Physics.OverlapBoxNonAlloc(center, menuBounds.extents * viewerScale, k_ColliderOverlaps, menuRotation) > 0) - { - foreach (var overlap in k_ColliderOverlaps) - { - if (overlap) - { - k_WorkspaceComponents.Clear(); - overlap.GetComponents(k_WorkspaceComponents); - if (k_WorkspaceComponents.Count > 0) - hoveringCollider = true; - - k_ButtonComponents.Clear(); - overlap.GetComponents(k_ButtonComponents); - if (k_ButtonComponents.Count > 0) - hoveringCollider = true; - } - } - } - - // Only set if hidden--value is reset every frame - if (hoveringCollider) - menuHideData.hideFlags |= MenuHideFlags.OverWorkspace; - } - - internal static bool IsValidHover(MultipleRayInputModule.RaycastSource source) - { - var go = source.draggedObject; - if (!go) - go = source.hoveredObject; - - if (!go) - return true; - - if (go == evr.gameObject) - return true; - - var eventData = source.eventData; - var rayOrigin = eventData.rayOrigin; - - DeviceData deviceData = null; - foreach (var currentDevice in evr.m_DeviceData) - { - if (currentDevice.rayOrigin == rayOrigin) - { - deviceData = currentDevice; - break; - } - } - - if (deviceData != null) - { - if (go.transform.IsChildOf(deviceData.rayOrigin)) // Don't let UI on this hand block the menu - return false; - - var scaledPointerDistance = eventData.pointerCurrentRaycast.distance / Viewer.GetViewerScale(); - var menuHideFlags = deviceData.menuHideData; - var mainMenu = deviceData.mainMenu; - IMenu openMenu = mainMenu; - if (deviceData.customMenu != null && menuHideFlags[mainMenu].hideFlags != 0) - openMenu = deviceData.customMenu; - - if (scaledPointerDistance < openMenu.localBounds.size.y + k_MenuHideMargin) - { - // Only set if hidden--value is reset every frame - menuHideFlags[openMenu].hideFlags |= MenuHideFlags.OverUI; - return true; - } - - return menuHideFlags[openMenu].hideFlags != 0; - } - - return true; - } - - internal static void UpdateAlternateMenuOnSelectionChanged(Transform rayOrigin) - { - if (rayOrigin == null) - return; - - SetAlternateMenuVisibility(rayOrigin, Selection.gameObjects.Length > 0); - } - - internal static void SetAlternateMenuVisibility(Transform rayOrigin, bool visible) - { - Rays.ForEachProxyDevice(deviceData => - { - var menuHideFlags = deviceData.menuHideData; - var alternateMenu = deviceData.alternateMenu; - if (alternateMenu != null) - { - // Set alternate menu visible on this rayOrigin and hide it on all others - var alternateMenuData = menuHideFlags[alternateMenu]; - if (deviceData.rayOrigin == rayOrigin && visible) - alternateMenuData.hideFlags &= ~MenuHideFlags.Hidden; - else - alternateMenuData.hideFlags |= MenuHideFlags.Hidden; - } - }); - } - - internal static void OnMainMenuActivatorSelected(Transform rayOrigin, Transform targetRayOrigin) - { - foreach (var deviceData in evr.m_DeviceData) - { - var mainMenu = deviceData.mainMenu; - if (mainMenu != null) - { - var customMenu = deviceData.customMenu; - var alternateMenu = deviceData.alternateMenu; - var menuHideData = deviceData.menuHideData; - var mainMenuHideData = menuHideData[mainMenu]; - var alternateMenuVisible = alternateMenu != null - && (menuHideData[alternateMenu].hideFlags & MenuHideFlags.Hidden) == 0; - - // Do not delay when showing via activator - mainMenuHideData.autoShowTime = 0; - - if (deviceData.rayOrigin == rayOrigin) - { - // Toggle main menu hidden flag - mainMenuHideData.hideFlags ^= MenuHideFlags.Hidden; - mainMenu.targetRayOrigin = targetRayOrigin; - } - else - { - mainMenuHideData.hideFlags |= MenuHideFlags.Hidden; - - var customMenuOverridden = customMenu != null && - (menuHideData[customMenu].hideFlags & MenuHideFlags.OtherMenu) != 0; - - // Move alternate menu if overriding custom menu - if (customMenuOverridden && alternateMenuVisible) - { - foreach (var otherDeviceData in evr.m_DeviceData) - { - if (deviceData == otherDeviceData) - continue; - - if (otherDeviceData.alternateMenu != null) - SetAlternateMenuVisibility(rayOrigin, true); - } - } - } - } - } - } - - static GameObject InstantiateMenuUI(Transform rayOrigin, IMenu prefab) - { - var ui = evr.GetNestedModule(); - GameObject go = null; - Rays.ForEachProxyDevice(deviceData => - { - var proxy = deviceData.proxy; - var otherRayOrigin = deviceData.rayOrigin; - if (proxy.rayOrigins.ContainsValue(rayOrigin) && otherRayOrigin != rayOrigin) - { - Transform menuOrigin; - if (proxy.menuOrigins.TryGetValue(otherRayOrigin, out menuOrigin)) - { - if (deviceData.customMenu == null) - { - go = ui.InstantiateUI(prefab.gameObject, menuOrigin, false); - - var customMenu = go.GetComponent(); - deviceData.customMenu = customMenu; - deviceData.menuHideData[customMenu] = new MenuHideData { hideFlags = 0 }; - } - } - } - }); - - return go; - } - - internal IMainMenu SpawnMainMenu(Type type, Transform rayOrigin) - { - if (!typeof(IMainMenu).IsAssignableFrom(type)) - return null; - - var mainMenu = (IMainMenu)ObjectUtils.AddComponent(type, evr.gameObject); - this.ConnectInterfaces(mainMenu, rayOrigin); - - return mainMenu; - } - - internal IAlternateMenu SpawnAlternateMenu(Type type, Transform rayOrigin) - { - if (!typeof(IAlternateMenu).IsAssignableFrom(type)) - return null; - - var alternateMenu = (IAlternateMenu)ObjectUtils.AddComponent(type, evr.gameObject); - this.ConnectInterfaces(alternateMenu, rayOrigin); - - return alternateMenu; - } - - internal IToolsMenu SpawnToolsMenu(Type type, Transform rayOrigin) - { - if (!typeof(IToolsMenu).IsAssignableFrom(type)) - return null; - - var menu = (IToolsMenu)ObjectUtils.AddComponent(type, evr.gameObject); - this.ConnectInterfaces(menu, rayOrigin); - - return menu; - } - - internal static void UpdateAlternateMenuActions() - { - var actionsModule = evr.GetModule(); - foreach (var deviceData in evr.m_DeviceData) - { - var altMenu = deviceData.alternateMenu; - if (altMenu != null) - altMenu.menuActions = actionsModule.menuActions; - } - } - - static bool IsMainMenuVisible(Transform rayOrigin) - { - foreach (var deviceData in evr.m_DeviceData) - { - if (deviceData.rayOrigin == rayOrigin) - return (deviceData.menuHideData[deviceData.mainMenu].hideFlags & MenuHideFlags.Hidden) == 0; - } - - return false; - } - } - } -} -#endif +#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor.Experimental.EditorVR.Menus; +using UnityEditor.Experimental.EditorVR.Modules; +using UnityEditor.Experimental.EditorVR.UI; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR.Core +{ + partial class EditorVR + { + const float k_MainMenuAutoHideDelay = 0.125f; + const float k_MainMenuAutoShowDelay = 0.25f; + + class Menus : Nested, IInterfaceConnector, ILateBindInterfaceMethods, IConnectInterfaces + { + internal class MenuHideData + { + public MenuHideFlags hideFlags = MenuHideFlags.Hidden; + public MenuHideFlags lastHideFlags = MenuHideFlags.Hidden; + public float autoHideTime; + public float autoShowTime; + } + + const float k_MenuHideMargin = 0.075f; + const float k_TwoHandHideDistance = 0.25f; + const int k_PossibleOverlaps = 16; + + readonly Dictionary m_MainMenus = new Dictionary(); + readonly Dictionary, ISettingsMenuProvider> m_SettingsMenuProviders = new Dictionary, ISettingsMenuProvider>(); + readonly Dictionary, ISettingsMenuItemProvider> m_SettingsMenuItemProviders = new Dictionary, ISettingsMenuItemProvider>(); + List m_MainMenuTools; + + // Local method use only -- created here to reduce garbage collection + static readonly List k_ActiveDeviceData = new List(); + static readonly List k_WorkspaceComponents = new List(); + static readonly List k_ButtonComponents = new List(); + static readonly Collider[] k_ColliderOverlaps = new Collider[k_PossibleOverlaps]; + + public Menus() + { + IInstantiateMenuUIMethods.instantiateMenuUI = InstantiateMenuUI; + IIsMainMenuVisibleMethods.isMainMenuVisible = IsMainMenuVisible; + IUsesCustomMenuOriginsMethods.getCustomMenuOrigin = GetCustomMenuOrigin; + IUsesCustomMenuOriginsMethods.getCustomAlternateMenuOrigin = GetCustomAlternateMenuOrigin; + } + + public void ConnectInterface(object target, object userData = null) + { + var rayOrigin = userData as Transform; + var settingsMenuProvider = target as ISettingsMenuProvider; + if (settingsMenuProvider != null) + { + m_SettingsMenuProviders[new KeyValuePair(target.GetType(), rayOrigin)] = settingsMenuProvider; + foreach (var kvp in m_MainMenus) + { + if (rayOrigin == null || kvp.Key == rayOrigin) + kvp.Value.AddSettingsMenu(settingsMenuProvider); + } + } + + var settingsMenuItemProvider = target as ISettingsMenuItemProvider; + if (settingsMenuItemProvider != null) + { + m_SettingsMenuItemProviders[new KeyValuePair(target.GetType(), rayOrigin)] = settingsMenuItemProvider; + foreach (var kvp in m_MainMenus) + { + if (rayOrigin == null || kvp.Key == rayOrigin) + kvp.Value.AddSettingsMenuItem(settingsMenuItemProvider); + } + } + + var mainMenu = target as IMainMenu; + if (mainMenu != null && rayOrigin != null) + { + mainMenu.menuTools = m_MainMenuTools; + mainMenu.menuWorkspaces = WorkspaceModule.workspaceTypes; + mainMenu.settingsMenuProviders = m_SettingsMenuProviders; + mainMenu.settingsMenuItemProviders = m_SettingsMenuItemProviders; + m_MainMenus[rayOrigin] = mainMenu; + } + + var menuOrigins = target as IUsesMenuOrigins; + if (menuOrigins != null) + { + Transform mainMenuOrigin; + var proxy = Rays.GetProxyForRayOrigin(rayOrigin); + if (proxy != null && proxy.menuOrigins.TryGetValue(rayOrigin, out mainMenuOrigin)) + { + menuOrigins.menuOrigin = mainMenuOrigin; + Transform alternateMenuOrigin; + if (proxy.alternateMenuOrigins.TryGetValue(rayOrigin, out alternateMenuOrigin)) + menuOrigins.alternateMenuOrigin = alternateMenuOrigin; + } + } + + var alternateMenu = target as IAlternateMenu; + if (alternateMenu != null) + AddAlternateMenu(alternateMenu, rayOrigin); + } + + public void DisconnectInterface(object target, object userData = null) + { + var rayOrigin = userData as Transform; + var settingsMenuProvider = target as ISettingsMenuProvider; + if (settingsMenuProvider != null) + { + foreach (var kvp in m_MainMenus) + { + if (rayOrigin == null || kvp.Key == rayOrigin) + kvp.Value.RemoveSettingsMenu(settingsMenuProvider); + } + + m_SettingsMenuProviders.Remove(new KeyValuePair(target.GetType(), rayOrigin)); + } + + var settingsMenuItemProvider = target as ISettingsMenuItemProvider; + if (settingsMenuItemProvider != null) + { + foreach (var kvp in m_MainMenus) + { + if (rayOrigin == null || kvp.Key == rayOrigin) + kvp.Value.RemoveSettingsMenuItem(settingsMenuItemProvider); + } + + m_SettingsMenuItemProviders.Remove(new KeyValuePair(target.GetType(), rayOrigin)); + } + + var mainMenu = target as IMainMenu; + if (mainMenu != null && rayOrigin != null) + m_MainMenus.Remove(rayOrigin); + + var alternateMenu = target as IAlternateMenu; + if (alternateMenu != null) + RemoveAlternateMenu(alternateMenu); + } + + static void AddAlternateMenu(IAlternateMenu alternateMenu, Transform rayOrigin) + { + foreach (var device in evr.m_DeviceData) + { + if (device.rayOrigin != rayOrigin) + continue; + + device.alternateMenus.Add(alternateMenu); + var menuHideData = new MenuHideData(); + device.menuHideData[alternateMenu] = menuHideData; + // Alternate menus must be visible the first frame or they are ignored in the priority list + menuHideData.hideFlags = 0; + + break; + } + } + + static void RemoveAlternateMenu(IAlternateMenu alternateMenu) + { + foreach (var device in evr.m_DeviceData) + { + device.alternateMenus.Remove(alternateMenu); + device.menuHideData.Remove(alternateMenu); + } + } + + public void LateBindInterfaceMethods(Tools provider) + { + m_MainMenuTools = provider.allTools.Where(t => !Tools.IsDefaultTool(t)).ToList(); // Don't show tools that can't be selected/toggled + } + + static void UpdateAlternateMenuForDevice(DeviceData deviceData) + { + var alternateMenu = deviceData.alternateMenu; + if (alternateMenu == null || !deviceData.menuHideData.ContainsKey(alternateMenu)) + return; + + alternateMenu.menuHideFlags = deviceData.currentTool is IExclusiveMode ? 0 : deviceData.menuHideData[alternateMenu].hideFlags; + + // Move the Tools Menu buttons to an alternate position if the radial menu will be shown + deviceData.toolsMenu.alternateMenuVisible = alternateMenu.menuHideFlags == 0 && alternateMenu is RadialMenu; + } + + static Transform GetCustomMenuOrigin(Transform rayOrigin) + { + Transform mainMenuOrigin = null; + + var proxy = Rays.GetProxyForRayOrigin(rayOrigin); + if (proxy != null) + { + var menuOrigins = proxy.menuOrigins; + if (menuOrigins.ContainsKey(rayOrigin)) + mainMenuOrigin = menuOrigins[rayOrigin]; + } + + return mainMenuOrigin; + } + + static Transform GetCustomAlternateMenuOrigin(Transform rayOrigin) + { + Transform alternateMenuOrigin = null; + + var proxy = Rays.GetProxyForRayOrigin(rayOrigin); + if (proxy != null) + { + var alternateMenuOrigins = proxy.alternateMenuOrigins; + if (alternateMenuOrigins.ContainsKey(rayOrigin)) + alternateMenuOrigin = alternateMenuOrigins[rayOrigin]; + } + + return alternateMenuOrigin; + } + + internal void UpdateMenuVisibilities() + { + k_ActiveDeviceData.Clear(); + Rays.ForEachProxyDevice(deviceData => { k_ActiveDeviceData.Add(deviceData); }); + + foreach (var deviceData in k_ActiveDeviceData) + { + foreach (var kvp in deviceData.menuHideData) + { + kvp.Value.hideFlags &= ~MenuHideFlags.Temporary; + } + } + + foreach (var deviceData in k_ActiveDeviceData) + { + IAlternateMenu alternateMenu = null; + var menuHideData = deviceData.menuHideData; + // Always display the highest-priority alternate menu, and hide all others. + var alternateMenus = deviceData.alternateMenus; + foreach (var menu in alternateMenus) + { + var hideData = menuHideData[menu]; + if ((hideData.hideFlags & MenuHideFlags.Hidden) == 0 + && (alternateMenu == null || menu.priority >= alternateMenu.priority)) + alternateMenu = menu; + + hideData.hideFlags |= MenuHideFlags.OtherMenu; + } + + deviceData.alternateMenu = alternateMenu; + menuHideData[alternateMenu].hideFlags = 0; + var mainMenu = deviceData.mainMenu; + var customMenu = deviceData.customMenu; + MenuHideData customMenuHideData = null; + + var mainMenuVisible = mainMenu != null && menuHideData[mainMenu].hideFlags == 0; + var mainMenuSupressed = mainMenu != null && ((menuHideData[mainMenu].hideFlags & MenuHideFlags.Occluded) != 0); + + var alternateMenuData = menuHideData[alternateMenu]; + var alternateMenuVisible = alternateMenuData.hideFlags == 0; + + var customMenuVisible = false; + if (customMenu != null) + { + customMenuHideData = menuHideData[customMenu]; + customMenuVisible = customMenuHideData.hideFlags == 0; + } + + // Temporarily hide customMenu if other menus are visible or should be + if (customMenuVisible && (mainMenuVisible || mainMenuSupressed)) + customMenuHideData.hideFlags |= MenuHideFlags.OtherMenu; + + // Temporarily hide alternateMenu if other menus are visible + if (alternateMenuVisible && (customMenuVisible || mainMenuVisible)) + alternateMenuData.hideFlags |= MenuHideFlags.OtherMenu; + + // Kick the alternate menu to the other hand if a main menu or custom menu is visible + if (alternateMenuVisible && (mainMenuVisible || customMenuVisible) && alternateMenu is RadialMenu) + { + foreach (var otherDeviceData in k_ActiveDeviceData) + { + if (otherDeviceData == deviceData) + continue; + + SetAlternateMenuVisibility(otherDeviceData.rayOrigin, true); + break; + } + } + + // Check if menu bounds overlap with any workspace colliders + foreach (var kvp in menuHideData) + { + CheckMenuColliderOverlaps(kvp.Key, kvp.Value); + } + + // Check if there are currently any held objects, or if the other hand is in proximity for scaling + CheckDirectSelection(deviceData, menuHideData, alternateMenuVisible); + } + + // Set show/hide timings + foreach (var deviceData in k_ActiveDeviceData) + { + foreach (var kvp in deviceData.menuHideData) + { + var hideFlags = kvp.Value.hideFlags; + if ((hideFlags & ~MenuHideFlags.Hidden & ~MenuHideFlags.OtherMenu) == 0) + kvp.Value.autoHideTime = Time.time; + + if (hideFlags != 0) + { + var menuHideData = kvp.Value; + menuHideData.lastHideFlags = menuHideData.hideFlags; + kvp.Value.autoShowTime = Time.time; + } + } + } + + // Apply MenuHideFlags to UI visibility + foreach (var deviceData in k_ActiveDeviceData) + { + var mainMenu = deviceData.mainMenu; + var mainMenuHideData = deviceData.menuHideData[mainMenu]; + var mainMenuHideFlags = mainMenuHideData.hideFlags; + var lastMainMenuHideFlags = mainMenuHideData.lastHideFlags; + + var permanentlyHidden = (mainMenuHideFlags & MenuHideFlags.Hidden) != 0; + var wasPermanentlyHidden = (lastMainMenuHideFlags & MenuHideFlags.Hidden) != 0; + + //Temporary states take effect after a delay + var temporarilyHidden = (mainMenuHideFlags & MenuHideFlags.Temporary) != 0 + && Time.time > mainMenuHideData.autoHideTime + k_MainMenuAutoHideDelay; + var wasTemporarilyHidden = (lastMainMenuHideFlags & MenuHideFlags.Temporary) != 0 + && Time.time > mainMenuHideData.autoShowTime + k_MainMenuAutoShowDelay; + + // If the menu is focused, only hide if Hidden is set (e.g. not temporary) in order to hide the selected tool + if (permanentlyHidden || wasPermanentlyHidden || !mainMenu.focus && (temporarilyHidden || wasTemporarilyHidden)) + mainMenu.menuHideFlags = mainMenuHideFlags; + + // Disable the main menu activator if any temporary states are set + deviceData.toolsMenu.mainMenuActivatorInteractable = (mainMenuHideFlags & MenuHideFlags.Temporary) == 0; + + // Show/hide custom menu, if it exists + var customMenu = deviceData.customMenu; + if (customMenu != null) + customMenu.menuHideFlags = deviceData.menuHideData[customMenu].hideFlags; + + var alternateMenus = deviceData.alternateMenus; + foreach (var menu in alternateMenus) + { + menu.menuHideFlags = deviceData.menuHideData[menu].hideFlags; + } + + UpdateAlternateMenuForDevice(deviceData); + Rays.UpdateRayForDevice(deviceData, deviceData.rayOrigin); + } + + evr.GetModule().UpdatePlayerHandleMaps(); + } + + static void CheckDirectSelection(DeviceData deviceData, Dictionary menuHideData, bool alternateMenuVisible) + { + var viewerScale = Viewer.GetViewerScale(); + var directSelection = evr.GetNestedModule(); + var rayOrigin = deviceData.rayOrigin; + var rayOriginPosition = rayOrigin.position; + var heldObjects = directSelection.GetHeldObjects(rayOrigin); + + // If this hand is holding any objects, hide its menus + var hasDirectSelection = heldObjects != null && heldObjects.Count > 0; + if (hasDirectSelection) + { + foreach (var kvp in menuHideData) + { + // Only set if hidden--value is reset every frame + kvp.Value.hideFlags |= MenuHideFlags.HasDirectSelection; + } + + foreach (var otherDeviceData in k_ActiveDeviceData) + { + if (otherDeviceData == deviceData) + continue; + + var otherRayOrigin = otherDeviceData.rayOrigin; + if (alternateMenuVisible) + SetAlternateMenuVisibility(otherRayOrigin, true); + + // If other hand is within range to do a two-handed scale, hide its menu as well + if (directSelection.IsHovering(otherRayOrigin) || directSelection.IsScaling(otherRayOrigin) + || Vector3.Distance(otherRayOrigin.position, rayOriginPosition) < k_TwoHandHideDistance * viewerScale) + { + foreach (var kvp in otherDeviceData.menuHideData) + { + // Only set if hidden--value is reset every frame + kvp.Value.hideFlags |= MenuHideFlags.HasDirectSelection; + } + break; + } + } + } + } + + static void CheckMenuColliderOverlaps(IMenu menu, MenuHideData menuHideData) + { + var menuBounds = menu.localBounds; + if (menuBounds.extents == Vector3.zero) + return; + + Array.Clear(k_ColliderOverlaps, 0, k_ColliderOverlaps.Length); + var hoveringCollider = false; + var menuTransform = menu.menuContent.transform; + var menuRotation = menuTransform.rotation; + var viewerScale = Viewer.GetViewerScale(); + var center = menuTransform.position + menuRotation * menuBounds.center * viewerScale; + if (Physics.OverlapBoxNonAlloc(center, menuBounds.extents * viewerScale, k_ColliderOverlaps, menuRotation) > 0) + { + foreach (var overlap in k_ColliderOverlaps) + { + if (overlap) + { + k_WorkspaceComponents.Clear(); + overlap.GetComponents(k_WorkspaceComponents); + if (k_WorkspaceComponents.Count > 0) + hoveringCollider = true; + + if (menu is MainMenu) + { + k_ButtonComponents.Clear(); + overlap.GetComponents(k_ButtonComponents); + if (k_ButtonComponents.Count > 0) + hoveringCollider = true; + } + } + } + } + + // Only set if hidden--value is reset every frame + if (hoveringCollider) + menuHideData.hideFlags |= MenuHideFlags.OverWorkspace; + } + + internal static bool IsValidHover(MultipleRayInputModule.RaycastSource source) + { + var go = source.draggedObject; + if (!go) + go = source.hoveredObject; + + if (!go) + return true; + + if (go == evr.gameObject) + return true; + + var eventData = source.eventData; + var rayOrigin = eventData.rayOrigin; + + DeviceData deviceData = null; + foreach (var currentDevice in evr.m_DeviceData) + { + if (currentDevice.rayOrigin == rayOrigin) + { + deviceData = currentDevice; + break; + } + } + + if (deviceData != null) + { + if (go.transform.IsChildOf(deviceData.rayOrigin)) // Don't let UI on this hand block the menu + return false; + + var scaledPointerDistance = eventData.pointerCurrentRaycast.distance / Viewer.GetViewerScale(); + var menuHideFlags = deviceData.menuHideData; + var mainMenu = deviceData.mainMenu; + IMenu openMenu = mainMenu; + if (deviceData.customMenu != null && menuHideFlags[mainMenu].hideFlags != 0) + openMenu = deviceData.customMenu; + + if (scaledPointerDistance < openMenu.localBounds.size.y + k_MenuHideMargin) + { + // Only set if hidden--value is reset every frame + menuHideFlags[openMenu].hideFlags |= MenuHideFlags.OverUI; + return true; + } + + return menuHideFlags[openMenu].hideFlags != 0; + } + + return true; + } + + internal static void UpdateAlternateMenuOnSelectionChanged(Transform rayOrigin) + { + if (rayOrigin == null) + return; + + SetAlternateMenuVisibility(rayOrigin, Selection.gameObjects.Length > 0); + } + + internal static void SetAlternateMenuVisibility(Transform rayOrigin, bool visible) + { + Rays.ForEachProxyDevice(deviceData => + { + foreach (var menu in deviceData.alternateMenus) + { + if (!(menu is IActionsMenu)) + continue; + + var menuHideFlags = deviceData.menuHideData; + // Set alternate menu visible on this rayOrigin and hide it on all others + var alternateMenuData = menuHideFlags[menu]; + if (deviceData.rayOrigin == rayOrigin && visible) + alternateMenuData.hideFlags &= ~MenuHideFlags.Hidden; + else + alternateMenuData.hideFlags |= MenuHideFlags.Hidden; + } + }); + } + + internal static void OnMainMenuActivatorSelected(Transform rayOrigin, Transform targetRayOrigin) + { + foreach (var deviceData in evr.m_DeviceData) + { + var mainMenu = deviceData.mainMenu; + if (mainMenu != null) + { + var customMenu = deviceData.customMenu; + var alternateMenu = deviceData.alternateMenu; + var menuHideData = deviceData.menuHideData; + var mainMenuHideData = menuHideData[mainMenu]; + var alternateMenuVisible = alternateMenu != null + && (menuHideData[alternateMenu].hideFlags & MenuHideFlags.Hidden) == 0; + + // Do not delay when showing via activator + mainMenuHideData.autoShowTime = 0; + + if (deviceData.rayOrigin == rayOrigin) + { + // Toggle main menu hidden flag + mainMenuHideData.hideFlags ^= MenuHideFlags.Hidden; + mainMenu.targetRayOrigin = targetRayOrigin; + } + else + { + mainMenuHideData.hideFlags |= MenuHideFlags.Hidden; + + var customMenuOverridden = customMenu != null && + (menuHideData[customMenu].hideFlags & MenuHideFlags.OtherMenu) != 0; + + // Move alternate menu if overriding custom menu + if (customMenuOverridden && alternateMenuVisible) + { + foreach (var otherDeviceData in evr.m_DeviceData) + { + if (deviceData == otherDeviceData) + continue; + + SetAlternateMenuVisibility(rayOrigin, true); + } + } + } + } + } + } + + static GameObject InstantiateMenuUI(Transform rayOrigin, IMenu prefab) + { + var ui = evr.GetNestedModule(); + GameObject go = null; + Rays.ForEachProxyDevice(deviceData => + { + var proxy = deviceData.proxy; + var otherRayOrigin = deviceData.rayOrigin; + if (proxy.rayOrigins.ContainsValue(rayOrigin) && otherRayOrigin != rayOrigin) + { + Transform menuOrigin; + if (proxy.menuOrigins.TryGetValue(otherRayOrigin, out menuOrigin)) + { + if (deviceData.customMenu == null) + { + go = ui.InstantiateUI(prefab.gameObject, menuOrigin, false); + + var customMenu = go.GetComponent(); + deviceData.customMenu = customMenu; + deviceData.menuHideData[customMenu] = new MenuHideData { hideFlags = 0 }; + } + } + } + }); + + return go; + } + + internal T SpawnMenu(Transform rayOrigin) where T : Component, IMenu + { + var mainMenu = ObjectUtils.AddComponent(evr.gameObject); + this.ConnectInterfaces(mainMenu, rayOrigin); + + return mainMenu; + } + + static bool IsMainMenuVisible(Transform rayOrigin) + { + foreach (var deviceData in evr.m_DeviceData) + { + if (deviceData.rayOrigin == rayOrigin) + return (deviceData.menuHideData[deviceData.mainMenu].hideFlags & MenuHideFlags.Hidden) == 0; + } + + return false; + } + } + } +} +#endif diff --git a/Scripts/Core/EditorVR.MiniWorlds.cs b/Scripts/Core/EditorVR.MiniWorlds.cs index 4d53efbcd..628d0a68f 100644 --- a/Scripts/Core/EditorVR.MiniWorlds.cs +++ b/Scripts/Core/EditorVR.MiniWorlds.cs @@ -383,8 +383,6 @@ internal void UpdateMiniWorlds() directSelection.ResumeGrabbers(incomingPreview.node); } - miniWorldRay.UpdatePreview(); // Otherwise the object is in the wrong position for a frame - if (!isContained) m_RayWasContained[originalRayOrigin] = false; //Prevent ray from showing } diff --git a/Scripts/Core/EditorVR.Rays.cs b/Scripts/Core/EditorVR.Rays.cs index aa8f83cea..194aff2c1 100644 --- a/Scripts/Core/EditorVR.Rays.cs +++ b/Scripts/Core/EditorVR.Rays.cs @@ -18,7 +18,7 @@ partial class EditorVR [SerializeField] ProxyExtras m_ProxyExtras; - class Rays : Nested, IInterfaceConnector, IForEachRayOrigin, IConnectInterfaces + class Rays : Nested, IInterfaceConnector, IForEachRayOrigin, IConnectInterfaces, IStandardIgnoreList { internal delegate void ForEachProxyDeviceCallback(DeviceData deviceData); @@ -35,6 +35,8 @@ class Rays : Nested, IInterfaceConnector, IForEachRayOrigin, IConnectInterfaces internal Transform lastSelectionRayOrigin { get; private set; } + public List ignoreList { private get; set; } + public Rays() { ISetDefaultRayColorMethods.setDefaultRayColor = SetDefaultRayColor; @@ -204,7 +206,7 @@ void OnProxyActiveChanged(IProxy proxy) var uiDistance = source.eventData.pointerCurrentRaycast.distance; // If the distance to a scene object is less than the distance to the hovered UI, invalidate the UI raycast - if (!isManipulator && raycastObject && sceneObjectDistance < uiDistance) + if (!isManipulator && raycastObject && sceneObjectDistance < uiDistance && !ignoreList.Contains(raycastObject)) return false; } diff --git a/Scripts/Core/EditorVR.Tools.cs b/Scripts/Core/EditorVR.Tools.cs index 7f5f24dd0..dc9dec36d 100644 --- a/Scripts/Core/EditorVR.Tools.cs +++ b/Scripts/Core/EditorVR.Tools.cs @@ -1,423 +1,428 @@ -#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor.Experimental.EditorVR.Menus; -using UnityEditor.Experimental.EditorVR.Modules; -using UnityEditor.Experimental.EditorVR.Tools; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; -using UnityEngine.InputNew; - -namespace UnityEditor.Experimental.EditorVR.Core -{ - partial class EditorVR - { - class Tools : Nested, IInterfaceConnector, IConnectInterfaces - { - internal class ToolData - { - public ITool tool; - public ActionMapInput input; - public Sprite icon; - } - - internal List allTools { get; private set; } - - readonly Dictionary> m_LinkedObjects = new Dictionary>(); - - public Tools() - { - allTools = ObjectUtils.GetImplementationsOfInterface(typeof(ITool)).ToList(); - - ILinkedObjectMethods.isSharedUpdater = IsSharedUpdater; - ISelectToolMethods.selectTool = SelectTool; - ISelectToolMethods.isToolActive = IsToolActive; - } - - public void ConnectInterface(object target, object userData = null) - { - var linkedObject = target as ILinkedObject; - if (linkedObject != null) - { - var type = target.GetType(); - List linkedObjectList; - if (!m_LinkedObjects.TryGetValue(type, out linkedObjectList)) - { - linkedObjectList = new List(); - m_LinkedObjects[type] = linkedObjectList; - } - - linkedObjectList.Add(linkedObject); - linkedObject.linkedObjects = linkedObjectList; - } - } - - public void DisconnectInterface(object target, object userData = null) - { - var linkedObject = target as ILinkedObject; - if (linkedObject != null) - { - // Delay removal of linked objects in case shutdown logic relies on them - // Specifically, SerialzePreferences in AnnotationTool calls IsSharedUpdater - EditorApplication.delayCall += () => - { - var type = target.GetType(); - List linkedObjectList; - if (!m_LinkedObjects.TryGetValue(type, out linkedObjectList)) - return; - - linkedObjectList.Remove(linkedObject); - linkedObject.linkedObjects = null; - - if (linkedObjectList.Count == 0) - m_LinkedObjects.Remove(type); - }; - } - } - - bool IsSharedUpdater(ILinkedObject linkedObject) - { - var type = linkedObject.GetType(); - return m_LinkedObjects[type].IndexOf(linkedObject) == 0; - } - - internal static bool IsDefaultTool(Type type) - { - return evr.m_DefaultTools.Contains(type); - } - - internal void SpawnDefaultTools(IProxy proxy) - { - var vacuumables = evr.GetNestedModule(); - var lockModule = evr.GetModule(); - var defaultTools = evr.m_DefaultTools; - - foreach (var deviceData in evr.m_DeviceData) - { - var inputDevice = deviceData.inputDevice; - ToolData selectionToolData = null; - - if (deviceData.proxy != proxy) - continue; - - var rayOrigin = deviceData.rayOrigin; - foreach (var toolType in defaultTools) - { - HashSet devices; - var toolData = SpawnTool(toolType, out devices, inputDevice, rayOrigin); - AddToolToDeviceData(toolData, devices); - - var tool = toolData.tool; - var selectionTool = tool as SelectionTool; - if (selectionTool) - { - selectionToolData = toolData; - selectionTool.hovered += lockModule.OnHovered; - } - - var vacuumTool = tool as VacuumTool; - if (vacuumTool) - { - vacuumTool.defaultOffset = WorkspaceModule.DefaultWorkspaceOffset; - vacuumTool.defaultTilt = WorkspaceModule.DefaultWorkspaceTilt; - vacuumTool.vacuumables = vacuumables.vacuumables; - } - } - - var menus = evr.GetNestedModule(); - var menuHideData = deviceData.menuHideData; - var mainMenu = menus.SpawnMainMenu(typeof(MainMenu), rayOrigin); - deviceData.mainMenu = mainMenu; - menuHideData[mainMenu] = new Menus.MenuHideData(); - - var alternateMenu = menus.SpawnAlternateMenu(typeof(RadialMenu), rayOrigin); - deviceData.alternateMenu = alternateMenu; - menuHideData[alternateMenu] = new Menus.MenuHideData(); - alternateMenu.itemWasSelected += Menus.UpdateAlternateMenuOnSelectionChanged; - - // Setup ToolsMenu - var toolsMenu = menus.SpawnToolsMenu(typeof(Experimental.EditorVR.Menus.ToolsMenu), rayOrigin); - deviceData.toolsMenu = toolsMenu; - toolsMenu.rayOrigin = rayOrigin; - toolsMenu.setButtonForType(typeof(IMainMenu), null); - toolsMenu.setButtonForType(typeof(SelectionTool), selectionToolData != null ? selectionToolData.icon : null); - } - - evr.GetModule().UpdatePlayerHandleMaps(); - } - - /// - /// Spawn a tool on a tool stack for a specific device (e.g. right hand). - /// - /// The tool to spawn - /// A list of the used devices coming from the action map - /// The input device whose tool stack the tool should be spawned on (optional). If not - /// specified, then it uses the action map to determine which devices the tool should be spawned on. - /// Returns tool that was spawned or null if the spawn failed. - ToolData SpawnTool(Type toolType, out HashSet usedDevices, InputDevice device, Transform rayOrigin) - { - usedDevices = new HashSet(); - if (!typeof(ITool).IsAssignableFrom(toolType)) - return null; - - var deviceSlots = new HashSet(); - var tool = ObjectUtils.AddComponent(toolType, evr.gameObject) as ITool; - - var actionMapInput = evr.GetModule().CreateActionMapInputForObject(tool, device); - if (actionMapInput != null) - { - usedDevices.UnionWith(actionMapInput.GetCurrentlyUsedDevices()); - InputUtils.CollectDeviceSlotsFromActionMapInput(actionMapInput, ref deviceSlots); - - actionMapInput.Reset(false); - } - - if (usedDevices.Count == 0) - usedDevices.Add(device); - - this.ConnectInterfaces(tool, rayOrigin); - - var icon = tool as IMenuIcon; - return new ToolData { tool = tool, input = actionMapInput, icon = icon != null ? icon.icon : null }; - } - - static void AddToolToDeviceData(ToolData toolData, HashSet devices) - { - foreach (var dd in evr.m_DeviceData) - { - if (devices.Contains(dd.inputDevice)) - AddToolToStack(dd, toolData); - } - } - - static bool IsToolActive(Transform targetRayOrigin, Type toolType) - { - var result = false; - - var deviceData = evr.m_DeviceData.FirstOrDefault(dd => dd.rayOrigin == targetRayOrigin); - if (deviceData != null) - result = deviceData.currentTool.GetType() == toolType; - - return result; - } - - internal bool SelectTool(Transform rayOrigin, Type toolType, bool despawnOnReselect = true, bool hideMenu = false) - { - var result = false; - var deviceInputModule = evr.GetModule(); - Rays.ForEachProxyDevice(deviceData => - { - if (deviceData.rayOrigin == rayOrigin) - { - var spawnTool = true; - var currentTool = deviceData.currentTool; - var currentToolType = currentTool.GetType(); - var currentToolIsSelect = currentToolType == typeof(SelectionTool); - var setSelectAsCurrentTool = toolType == typeof(SelectionTool) && !currentToolIsSelect; - var toolsMenu = deviceData.toolsMenu; - - // If this tool was on the current device already, remove it, if it is selected while already being the current tool - var despawn = (!currentToolIsSelect && currentToolType == toolType && despawnOnReselect) || setSelectAsCurrentTool; // || setSelectAsCurrentTool || toolType == typeof(IMainMenu); - if (currentTool != null && despawn) - { - DespawnTool(deviceData, currentTool); - - if (!setSelectAsCurrentTool) - { - // Delete a button of the first type parameter - // Then select a button the second type param (the new current tool) - // Don't spawn a new tool, since we are only removing the old tool - toolsMenu.deleteToolsMenuButton(toolType, currentToolType); - } - else if (setSelectAsCurrentTool) - { - // Set the selection tool as the active tool, if select is to be the new current tool - toolsMenu.setButtonForType(typeof(SelectionTool), null); - } - - spawnTool = false; - } - - if (spawnTool && !IsDefaultTool(toolType)) - { - var evrDeviceData = evr.m_DeviceData; - - // Spawn tool and collect all devices that this tool will need - HashSet usedDevices; - var device = deviceData.inputDevice; - var newTool = SpawnTool(toolType, out usedDevices, device, rayOrigin); - var multiTool = newTool.tool as IMultiDeviceTool; - if (multiTool != null) - { - multiTool.primary = true; - Rays.ForEachProxyDevice(otherDeviceData => - { - if (otherDeviceData != deviceData) - { - HashSet otherUsedDevices; - var otherToolData = SpawnTool(toolType, out otherUsedDevices, otherDeviceData.inputDevice, otherDeviceData.rayOrigin); - foreach (var dd in evrDeviceData) - { - if (!otherUsedDevices.Contains(dd.inputDevice)) - continue; - - var otherCurrentTool = otherDeviceData.currentTool; - if (otherCurrentTool != null) // Remove the current tool on all devices this tool will be spawned on - DespawnTool(otherDeviceData, otherCurrentTool); - - AddToolToStack(dd, otherToolData); - } - } - }); - } - - // Exclusive mode tools always take over all tool stacks - if (newTool.tool is IExclusiveMode) - { - foreach (var dev in evrDeviceData) - { - usedDevices.Add(dev.inputDevice); - } - } - - foreach (var data in evrDeviceData) - { - if (!usedDevices.Contains(data.inputDevice)) - continue; - - if (currentTool != null) // Remove the current tool on all devices this tool will be spawned on - DespawnTool(deviceData, currentTool); - - AddToolToStack(data, newTool); - - toolsMenu.setButtonForType(toolType, newTool.icon); - } - } - - deviceInputModule.UpdatePlayerHandleMaps(); - result = spawnTool; - } - else if (hideMenu) - { - deviceData.menuHideData[deviceData.mainMenu].hideFlags |= MenuHideFlags.Hidden; - } - }); - - return result; - } - - void DespawnTool(DeviceData deviceData, ITool tool) - { - var toolType = tool.GetType(); - if (!IsDefaultTool(toolType)) - { - // Remove the tool if it is the current tool on this device tool stack - if (deviceData.currentTool == tool) - { - var topTool = deviceData.toolData.Peek(); - if (topTool == null || topTool.tool != deviceData.currentTool) - { - Debug.LogError("Tool at top of stack is not current tool."); - return; - } - - var oldTool = deviceData.toolData.Pop(); - oldTool.input.active = false; - topTool = deviceData.toolData.Peek(); - deviceData.currentTool = topTool.tool; - - // Pop this tool off any other stack that references it (for single instance tools) - foreach (var otherDeviceData in evr.m_DeviceData) - { - if (otherDeviceData != deviceData) - { - // Pop this tool off any other stack that references it (for single instance, multi-device tools) - var otherTool = otherDeviceData.currentTool; - if (otherTool == tool) - { - oldTool = otherDeviceData.toolData.Pop(); - oldTool.input.active = false; - var otherToolData = otherDeviceData.toolData.Peek(); - if (otherToolData != null) - otherDeviceData.currentTool = otherToolData.tool; - - if (tool is IExclusiveMode) - SetToolsEnabled(otherDeviceData, true); - } - - // Pop this tool of any other stack that references it (for IMultiDeviceTools) - if (tool is IMultiDeviceTool) - { - if (otherTool.GetType() == toolType) - { - oldTool = otherDeviceData.toolData.Pop(); - oldTool.input.active = false; - var otherToolData = otherDeviceData.toolData.Peek(); - if (otherToolData != null) - { - otherDeviceData.currentTool = otherToolData.tool; - this.DisconnectInterfaces(otherTool, otherDeviceData.rayOrigin); - ObjectUtils.Destroy(otherTool as MonoBehaviour); - } - } - } - - // If the tool had a custom menu, the custom menu would spawn on the opposite device - var customMenu = otherDeviceData.customMenu; - if (customMenu != null) - { - otherDeviceData.menuHideData.Remove(customMenu); - otherDeviceData.customMenu = null; - } - } - } - } - this.DisconnectInterfaces(tool, deviceData.rayOrigin); - - // Exclusive tools disable other tools underneath, so restore those - if (tool is IExclusiveMode) - SetToolsEnabled(deviceData, true); - - ObjectUtils.Destroy(tool as MonoBehaviour); - } - } - - static void SetToolsEnabled(DeviceData deviceData, bool value) - { - foreach (var td in deviceData.toolData) - { - var mb = td.tool as MonoBehaviour; - if (mb) - mb.enabled = value; - } - } - - static void AddToolToStack(DeviceData deviceData, ToolData toolData) - { - if (toolData != null) - { - // Exclusive tools render other tools disabled while they are on the stack - if (toolData.tool is IExclusiveMode) - SetToolsEnabled(deviceData, false); - - deviceData.toolData.Push(toolData); - deviceData.currentTool = toolData.tool; - } - } - - internal static void UpdatePlayerHandleMaps(List maps) - { - foreach (var deviceData in evr.m_DeviceData) - { - foreach (var td in deviceData.toolData) - { - if (td.input != null && !maps.Contains(td.input)) - maps.Add(td.input); - } - } - } - } - } -} -#endif +#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor.Experimental.EditorVR.Menus; +using UnityEditor.Experimental.EditorVR.Modules; +using UnityEditor.Experimental.EditorVR.Tools; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; +using UnityEngine.InputNew; + +namespace UnityEditor.Experimental.EditorVR.Core +{ + partial class EditorVR + { + class Tools : Nested, IInterfaceConnector, IConnectInterfaces + { + internal class ToolData + { + public ITool tool; + public ActionMapInput input; + public Sprite icon; + } + + internal List allTools { get; private set; } + + readonly Dictionary> m_LinkedObjects = new Dictionary>(); + + public Tools() + { + allTools = ObjectUtils.GetImplementationsOfInterface(typeof(ITool)).ToList(); + + ILinkedObjectMethods.isSharedUpdater = IsSharedUpdater; + ISelectToolMethods.selectTool = SelectTool; + ISelectToolMethods.isToolActive = IsToolActive; + } + + public void ConnectInterface(object target, object userData = null) + { + var linkedObject = target as ILinkedObject; + if (linkedObject != null) + { + var type = target.GetType(); + List linkedObjectList; + if (!m_LinkedObjects.TryGetValue(type, out linkedObjectList)) + { + linkedObjectList = new List(); + m_LinkedObjects[type] = linkedObjectList; + } + + linkedObjectList.Add(linkedObject); + linkedObject.linkedObjects = linkedObjectList; + } + } + + public void DisconnectInterface(object target, object userData = null) + { + var linkedObject = target as ILinkedObject; + if (linkedObject != null) + { + // Delay removal of linked objects in case shutdown logic relies on them + // Specifically, SerialzePreferences in AnnotationTool calls IsSharedUpdater + EditorApplication.delayCall += () => + { + var type = target.GetType(); + List linkedObjectList; + if (!m_LinkedObjects.TryGetValue(type, out linkedObjectList)) + return; + + linkedObjectList.Remove(linkedObject); + linkedObject.linkedObjects = null; + + if (linkedObjectList.Count == 0) + m_LinkedObjects.Remove(type); + }; + } + } + + bool IsSharedUpdater(ILinkedObject linkedObject) + { + var type = linkedObject.GetType(); + return m_LinkedObjects[type].IndexOf(linkedObject) == 0; + } + + internal static bool IsDefaultTool(Type type) + { + return evr.m_DefaultTools.Contains(type); + } + + internal void SpawnDefaultTools(IProxy proxy) + { + var vacuumables = evr.GetNestedModule(); + var lockModule = evr.GetModule(); + var defaultTools = evr.m_DefaultTools; + + foreach (var deviceData in evr.m_DeviceData) + { + var inputDevice = deviceData.inputDevice; + ToolData selectionToolData = null; + + if (deviceData.proxy != proxy) + continue; + + var rayOrigin = deviceData.rayOrigin; + foreach (var toolType in defaultTools) + { + HashSet devices; + var toolData = SpawnTool(toolType, out devices, inputDevice, rayOrigin); + AddToolToDeviceData(toolData, devices); + + var tool = toolData.tool; + var selectionTool = tool as SelectionTool; + if (selectionTool) + { + selectionToolData = toolData; + selectionTool.hovered += lockModule.OnHovered; + } + + var vacuumTool = tool as VacuumTool; + if (vacuumTool) + { + vacuumTool.defaultOffset = WorkspaceModule.DefaultWorkspaceOffset; + vacuumTool.defaultTilt = WorkspaceModule.DefaultWorkspaceTilt; + vacuumTool.vacuumables = vacuumables.vacuumables; + } + } + + var menus = evr.GetNestedModule(); + var menuHideData = deviceData.menuHideData; + var mainMenu = menus.SpawnMenu(rayOrigin); + deviceData.mainMenu = mainMenu; + menuHideData[mainMenu] = new Menus.MenuHideData(); + + var radialMenu = menus.SpawnMenu(rayOrigin); + menuHideData[radialMenu] = new Menus.MenuHideData(); + radialMenu.itemWasSelected += Menus.UpdateAlternateMenuOnSelectionChanged; + + var undoMenu = menus.SpawnMenu(rayOrigin); + var hideData = new Menus.MenuHideData(); + menuHideData[undoMenu] = hideData; + hideData.hideFlags = 0; + + // Setup ToolsMenu + var toolsMenu = ObjectUtils.AddComponent(evr.gameObject); + this.ConnectInterfaces(toolsMenu, rayOrigin); + deviceData.toolsMenu = toolsMenu; + toolsMenu.rayOrigin = rayOrigin; + toolsMenu.setButtonForType(typeof(IMainMenu), null); + toolsMenu.setButtonForType(typeof(SelectionTool), selectionToolData != null ? selectionToolData.icon : null); + } + + evr.GetModule().UpdatePlayerHandleMaps(); + } + + /// + /// Spawn a tool on a tool stack for a specific device (e.g. right hand). + /// + /// The tool to spawn + /// A list of the used devices coming from the action map + /// The input device whose tool stack the tool should be spawned on (optional). If not + /// specified, then it uses the action map to determine which devices the tool should be spawned on. + /// Returns tool that was spawned or null if the spawn failed. + ToolData SpawnTool(Type toolType, out HashSet usedDevices, InputDevice device, Transform rayOrigin) + { + usedDevices = new HashSet(); + if (!typeof(ITool).IsAssignableFrom(toolType)) + return null; + + var deviceSlots = new HashSet(); + var tool = ObjectUtils.AddComponent(toolType, evr.gameObject) as ITool; + + var actionMapInput = evr.GetModule().CreateActionMapInputForObject(tool, device); + if (actionMapInput != null) + { + usedDevices.UnionWith(actionMapInput.GetCurrentlyUsedDevices()); + InputUtils.CollectDeviceSlotsFromActionMapInput(actionMapInput, ref deviceSlots); + + actionMapInput.Reset(false); + } + + if (usedDevices.Count == 0) + usedDevices.Add(device); + + this.ConnectInterfaces(tool, rayOrigin); + + var icon = tool as IMenuIcon; + return new ToolData { tool = tool, input = actionMapInput, icon = icon != null ? icon.icon : null }; + } + + static void AddToolToDeviceData(ToolData toolData, HashSet devices) + { + foreach (var dd in evr.m_DeviceData) + { + if (devices.Contains(dd.inputDevice)) + AddToolToStack(dd, toolData); + } + } + + static bool IsToolActive(Transform targetRayOrigin, Type toolType) + { + var result = false; + + var deviceData = evr.m_DeviceData.FirstOrDefault(dd => dd.rayOrigin == targetRayOrigin); + if (deviceData != null) + result = deviceData.currentTool.GetType() == toolType; + + return result; + } + + internal bool SelectTool(Transform rayOrigin, Type toolType, bool despawnOnReselect = true, bool hideMenu = false) + { + var result = false; + var deviceInputModule = evr.GetModule(); + Rays.ForEachProxyDevice(deviceData => + { + if (deviceData.rayOrigin == rayOrigin) + { + var spawnTool = true; + var currentTool = deviceData.currentTool; + var currentToolType = currentTool.GetType(); + var currentToolIsSelect = currentToolType == typeof(SelectionTool); + var setSelectAsCurrentTool = toolType == typeof(SelectionTool) && !currentToolIsSelect; + var toolsMenu = deviceData.toolsMenu; + + // If this tool was on the current device already, remove it, if it is selected while already being the current tool + var despawn = (!currentToolIsSelect && currentToolType == toolType && despawnOnReselect) || setSelectAsCurrentTool; // || setSelectAsCurrentTool || toolType == typeof(IMainMenu); + if (currentTool != null && despawn) + { + DespawnTool(deviceData, currentTool); + + if (!setSelectAsCurrentTool) + { + // Delete a button of the first type parameter + // Then select a button the second type param (the new current tool) + // Don't spawn a new tool, since we are only removing the old tool + toolsMenu.deleteToolsMenuButton(toolType, currentToolType); + } + else if (setSelectAsCurrentTool) + { + // Set the selection tool as the active tool, if select is to be the new current tool + toolsMenu.setButtonForType(typeof(SelectionTool), null); + } + + spawnTool = false; + } + + if (spawnTool && !IsDefaultTool(toolType)) + { + var evrDeviceData = evr.m_DeviceData; + + // Spawn tool and collect all devices that this tool will need + HashSet usedDevices; + var device = deviceData.inputDevice; + var newTool = SpawnTool(toolType, out usedDevices, device, rayOrigin); + var multiTool = newTool.tool as IMultiDeviceTool; + if (multiTool != null) + { + multiTool.primary = true; + Rays.ForEachProxyDevice(otherDeviceData => + { + if (otherDeviceData != deviceData) + { + HashSet otherUsedDevices; + var otherToolData = SpawnTool(toolType, out otherUsedDevices, otherDeviceData.inputDevice, otherDeviceData.rayOrigin); + foreach (var dd in evrDeviceData) + { + if (!otherUsedDevices.Contains(dd.inputDevice)) + continue; + + var otherCurrentTool = otherDeviceData.currentTool; + if (otherCurrentTool != null) // Remove the current tool on all devices this tool will be spawned on + DespawnTool(otherDeviceData, otherCurrentTool); + + AddToolToStack(dd, otherToolData); + } + } + }); + } + + // Exclusive mode tools always take over all tool stacks + if (newTool.tool is IExclusiveMode) + { + foreach (var dev in evrDeviceData) + { + usedDevices.Add(dev.inputDevice); + } + } + + foreach (var data in evrDeviceData) + { + if (!usedDevices.Contains(data.inputDevice)) + continue; + + if (currentTool != null) // Remove the current tool on all devices this tool will be spawned on + DespawnTool(deviceData, currentTool); + + AddToolToStack(data, newTool); + + toolsMenu.setButtonForType(toolType, newTool.icon); + } + } + + deviceInputModule.UpdatePlayerHandleMaps(); + result = spawnTool; + } + else if (hideMenu) + { + deviceData.menuHideData[deviceData.mainMenu].hideFlags |= MenuHideFlags.Hidden; + } + }); + + return result; + } + + void DespawnTool(DeviceData deviceData, ITool tool) + { + var toolType = tool.GetType(); + if (!IsDefaultTool(toolType)) + { + // Remove the tool if it is the current tool on this device tool stack + if (deviceData.currentTool == tool) + { + var topTool = deviceData.toolData.Peek(); + if (topTool == null || topTool.tool != deviceData.currentTool) + { + Debug.LogError("Tool at top of stack is not current tool."); + return; + } + + var oldTool = deviceData.toolData.Pop(); + oldTool.input.active = false; + topTool = deviceData.toolData.Peek(); + deviceData.currentTool = topTool.tool; + + // Pop this tool off any other stack that references it (for single instance tools) + foreach (var otherDeviceData in evr.m_DeviceData) + { + if (otherDeviceData != deviceData) + { + // Pop this tool off any other stack that references it (for single instance, multi-device tools) + var otherTool = otherDeviceData.currentTool; + if (otherTool == tool) + { + oldTool = otherDeviceData.toolData.Pop(); + oldTool.input.active = false; + var otherToolData = otherDeviceData.toolData.Peek(); + if (otherToolData != null) + otherDeviceData.currentTool = otherToolData.tool; + + if (tool is IExclusiveMode) + SetToolsEnabled(otherDeviceData, true); + } + + // Pop this tool of any other stack that references it (for IMultiDeviceTools) + if (tool is IMultiDeviceTool) + { + if (otherTool.GetType() == toolType) + { + oldTool = otherDeviceData.toolData.Pop(); + oldTool.input.active = false; + var otherToolData = otherDeviceData.toolData.Peek(); + if (otherToolData != null) + { + otherDeviceData.currentTool = otherToolData.tool; + this.DisconnectInterfaces(otherTool, otherDeviceData.rayOrigin); + ObjectUtils.Destroy(otherTool as MonoBehaviour); + } + } + } + + // If the tool had a custom menu, the custom menu would spawn on the opposite device + var customMenu = otherDeviceData.customMenu; + if (customMenu != null) + { + otherDeviceData.menuHideData.Remove(customMenu); + otherDeviceData.customMenu = null; + } + } + } + } + this.DisconnectInterfaces(tool, deviceData.rayOrigin); + + // Exclusive tools disable other tools underneath, so restore those + if (tool is IExclusiveMode) + SetToolsEnabled(deviceData, true); + + ObjectUtils.Destroy(tool as MonoBehaviour); + } + } + + static void SetToolsEnabled(DeviceData deviceData, bool value) + { + foreach (var td in deviceData.toolData) + { + var mb = td.tool as MonoBehaviour; + if (mb) + mb.enabled = value; + } + } + + static void AddToolToStack(DeviceData deviceData, ToolData toolData) + { + if (toolData != null) + { + // Exclusive tools render other tools disabled while they are on the stack + if (toolData.tool is IExclusiveMode) + SetToolsEnabled(deviceData, false); + + deviceData.toolData.Push(toolData); + deviceData.currentTool = toolData.tool; + } + } + + internal static void UpdatePlayerHandleMaps(List maps) + { + foreach (var deviceData in evr.m_DeviceData) + { + foreach (var td in deviceData.toolData) + { + if (td.input != null && !maps.Contains(td.input)) + maps.Add(td.input); + } + } + } + } + } +} +#endif diff --git a/Scripts/Core/EditorVR.cs b/Scripts/Core/EditorVR.cs index 2714e7d7e..b1aea5fd3 100644 --- a/Scripts/Core/EditorVR.cs +++ b/Scripts/Core/EditorVR.cs @@ -1,559 +1,570 @@ -#if UNITY_EDITOR -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor.Experimental.EditorVR; -using UnityEditor.Experimental.EditorVR.Extensions; -using UnityEditor.Experimental.EditorVR.Modules; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; -using UnityEngine.InputNew; - -[assembly: OptionalDependency("PolyToolkit.PolyApi", "INCLUDE_POLY_TOOLKIT")] - -namespace UnityEditor.Experimental.EditorVR.Core -{ -#if UNITY_2017_2_OR_NEWER - [InitializeOnLoad] - [RequiresTag(k_VRPlayerTag)] - sealed partial class EditorVR : MonoBehaviour, IConnectInterfaces - { - const string k_ShowGameObjects = "EditorVR.ShowGameObjects"; - const string k_PreserveLayout = "EditorVR.PreserveLayout"; - const string k_SerializedPreferences = "EditorVR.SerializedPreferences"; - const string k_VRPlayerTag = "VRPlayer"; - - Dictionary m_NestedModules = new Dictionary(); - Dictionary m_Modules = new Dictionary(); - - Interfaces m_Interfaces; - Type[] m_DefaultTools; - - event Action selectionChanged; - - readonly List m_DeviceData = new List(); - - bool m_HasDeserialized; - - static bool s_IsInitialized; - - static EditorVR s_Instance; - - static HideFlags defaultHideFlags - { - get { return showGameObjects ? HideFlags.DontSave : HideFlags.HideAndDontSave; } - } - - static bool showGameObjects - { - get { return EditorPrefs.GetBool(k_ShowGameObjects, false); } - set { EditorPrefs.SetBool(k_ShowGameObjects, value); } - } - - static bool preserveLayout - { - get { return EditorPrefs.GetBool(k_PreserveLayout, true); } - set { EditorPrefs.SetBool(k_PreserveLayout, value); } - } - - static string serializedPreferences - { - get { return EditorPrefs.GetString(k_SerializedPreferences, string.Empty); } - set { EditorPrefs.SetString(k_SerializedPreferences, value); } - } - - internal static Type[] defaultTools { get; set; } - - class DeviceData - { - public IProxy proxy; - public InputDevice inputDevice; - public Node node; - public Transform rayOrigin; - public readonly Stack toolData = new Stack(); - public IMainMenu mainMenu; - public IAlternateMenu alternateMenu; - public ITool currentTool; - public IMenu customMenu; - public IToolsMenu toolsMenu; - public readonly Dictionary menuHideData = new Dictionary(); - } - - class Nested - { - public static EditorVR evr { protected get; set; } - - internal virtual void OnDestroy() { } - } - - static void ResetPreferences() - { - EditorPrefs.DeleteKey(k_ShowGameObjects); - EditorPrefs.DeleteKey(k_PreserveLayout); - EditorPrefs.DeleteKey(k_SerializedPreferences); - } - - // Code from the previous static constructor moved here to allow for testability - static void HandleInitialization() - { - if (!s_IsInitialized) - { - s_IsInitialized = true; - - if (!PlayerSettings.virtualRealitySupported) - Debug.Log("EditorVR requires VR support. Please check Virtual Reality Supported in Edit->Project Settings->Player->Other Settings"); - -#if !ENABLE_OVR_INPUT && !ENABLE_STEAMVR_INPUT && !ENABLE_SIXENSE_INPUT - Debug.Log("EditorVR requires at least one partner (e.g. Oculus, Vive) SDK to be installed for input. You can download these from the Asset Store or from the partner's website"); -#endif - } - // Add EVR tags and layers if they don't exist - var tags = TagManager.GetRequiredTags(); - var layers = TagManager.GetRequiredLayers(); - - foreach (var tag in tags) - { - TagManager.AddTag(tag); - } - - foreach (var layer in layers) - { - TagManager.AddLayer(layer); - } - } - - void Awake() - { - s_Instance = this; // Used only by PreferencesGUI - Nested.evr = this; // Set this once for the convenience of all nested classes - m_DefaultTools = defaultTools; - SetHideFlags(defaultHideFlags); - ClearDeveloperConsoleIfNecessary(); - HandleInitialization(); - - m_Interfaces = (Interfaces)AddNestedModule(typeof(Interfaces)); - AddModule(); // Added here in case any nested modules have preference serialization - AddNestedModule(typeof(SerializedPreferencesModuleConnector)); - - var nestedClassTypes = ObjectUtils.GetExtensionsOfClass(typeof(Nested)); - foreach (var type in nestedClassTypes) - { - AddNestedModule(type); - } - LateBindNestedModules(nestedClassTypes); - - AddModule(); - AddModule(); - - var viewer = GetNestedModule(); - viewer.preserveCameraRig = preserveLayout; - viewer.InitializeCamera(); - - var deviceInputModule = AddModule(); - deviceInputModule.InitializePlayerHandle(); - deviceInputModule.CreateDefaultActionMapInputs(); - deviceInputModule.processInput = ProcessInput; - deviceInputModule.updatePlayerHandleMaps = Tools.UpdatePlayerHandleMaps; - deviceInputModule.inputDeviceForRayOrigin = rayOrigin => - (from deviceData in m_DeviceData - where deviceData.rayOrigin == rayOrigin - select deviceData.inputDevice).FirstOrDefault(); - - GetNestedModule().Initialize(); - - AddModule(); - - var multipleRayInputModule = GetModule(); - - var dragAndDropModule = AddModule(); - multipleRayInputModule.rayEntered += dragAndDropModule.OnRayEntered; - multipleRayInputModule.rayExited += dragAndDropModule.OnRayExited; - multipleRayInputModule.dragStarted += dragAndDropModule.OnDragStarted; - multipleRayInputModule.dragEnded += dragAndDropModule.OnDragEnded; - - var tooltipModule = AddModule(); - this.ConnectInterfaces(tooltipModule); - multipleRayInputModule.rayEntered += tooltipModule.OnRayEntered; - multipleRayInputModule.rayHovering += tooltipModule.OnRayHovering; - multipleRayInputModule.rayExited += tooltipModule.OnRayExited; - - AddModule(); - AddModule(); - - var lockModule = AddModule(); - lockModule.updateAlternateMenu = (rayOrigin, o) => Menus.SetAlternateMenuVisibility(rayOrigin, o != null); - - AddModule(); - - var spatialHashModule = AddModule(); - spatialHashModule.shouldExcludeObject = go => go.GetComponentInParent(); - spatialHashModule.Setup(); - - var intersectionModule = AddModule(); - this.ConnectInterfaces(intersectionModule); - intersectionModule.Setup(spatialHashModule.spatialHash); - - AddModule(); - - var vacuumables = GetNestedModule(); - - var miniWorlds = GetNestedModule(); - var workspaceModule = AddModule(); - workspaceModule.preserveWorkspaces = preserveLayout; - workspaceModule.workspaceCreated += vacuumables.OnWorkspaceCreated; - workspaceModule.workspaceCreated += miniWorlds.OnWorkspaceCreated; - workspaceModule.workspaceCreated += workspace => { deviceInputModule.UpdatePlayerHandleMaps(); }; - workspaceModule.workspaceDestroyed += vacuumables.OnWorkspaceDestroyed; - workspaceModule.workspaceDestroyed += miniWorlds.OnWorkspaceDestroyed; - - UnityBrandColorScheme.sessionGradient = UnityBrandColorScheme.GetRandomCuratedLightGradient(); - UnityBrandColorScheme.saturatedSessionGradient = UnityBrandColorScheme.GetRandomCuratedGradient(); - - var sceneObjectModule = AddModule(); - sceneObjectModule.tryPlaceObject = (obj, targetScale) => - { - foreach (var miniWorld in miniWorlds.worlds) - { - if (!miniWorld.Contains(obj.position)) - continue; - - var referenceTransform = miniWorld.referenceTransform; - obj.transform.parent = null; - obj.position = referenceTransform.position + Vector3.Scale(miniWorld.miniWorldTransform.InverseTransformPoint(obj.position), miniWorld.referenceTransform.localScale); - obj.rotation = referenceTransform.rotation * Quaternion.Inverse(miniWorld.miniWorldTransform.rotation) * obj.rotation; - obj.localScale = Vector3.Scale(Vector3.Scale(obj.localScale, referenceTransform.localScale), miniWorld.miniWorldTransform.lossyScale.Inverse()); - - spatialHashModule.AddObject(obj.gameObject); - return true; - } - - return false; - }; - - AddModule(); - AddModule(); - AddModule(); - - AddModule(); - - AddModule(); - - //TODO: External module support (removes need for CCU in this instance) -#if INCLUDE_POLY_TOOLKIT - AddModule(); -#endif - - viewer.AddPlayerModel(); - - GetNestedModule().CreateAllProxies(); - - // In case we have anything selected at start, set up manipulators, inspector, etc. - EditorApplication.delayCall += OnSelectionChanged; - } - - IEnumerator Start() - { - var leftHandFound = false; - var rightHandFound = false; - - // Some components depend on both hands existing (e.g. MiniWorldWorkspace), so make sure they exist before restoring - while (!(leftHandFound && rightHandFound)) - { - Rays.ForEachProxyDevice(deviceData => - { - if (deviceData.node == Node.LeftHand) - leftHandFound = true; - - if (deviceData.node == Node.RightHand) - rightHandFound = true; - }); - - yield return null; - } - - var viewer = GetNestedModule(); - while (!viewer.hmdReady) - yield return null; - - GetModule().DeserializePreferences(serializedPreferences); - m_HasDeserialized = true; - } - - static void ClearDeveloperConsoleIfNecessary() - { - var asm = Assembly.GetAssembly(typeof(Editor)); - var consoleWindowType = asm.GetType("UnityEditor.ConsoleWindow"); - - EditorWindow window = null; - foreach (var w in Resources.FindObjectsOfTypeAll()) - { - if (w.GetType() == consoleWindowType) - { - window = w; - break; - } - } - - if (window) - { - var consoleFlagsType = consoleWindowType.GetNestedType("ConsoleFlags", BindingFlags.NonPublic); - var names = Enum.GetNames(consoleFlagsType); - var values = Enum.GetValues(consoleFlagsType); - var clearOnPlayFlag = values.GetValue(Array.IndexOf(names, "ClearOnPlay")); - - var hasFlagMethod = consoleWindowType.GetMethod("HasFlag", BindingFlags.NonPublic | BindingFlags.Static); - var result = (bool)hasFlagMethod.Invoke(window, new[] { clearOnPlayFlag }); - - if (result) - { - var logEntries = asm.GetType("UnityEditor.LogEntries"); - var clearMethod = logEntries.GetMethod("Clear", BindingFlags.Static | BindingFlags.Public); - clearMethod.Invoke(null, null); - } - } - } - - void OnSelectionChanged() - { - if (selectionChanged != null) - selectionChanged(); - - Menus.UpdateAlternateMenuOnSelectionChanged(GetNestedModule().lastSelectionRayOrigin); - } - - void OnEnable() - { - Selection.selectionChanged += OnSelectionChanged; - } - - void OnDisable() - { - Selection.selectionChanged -= OnSelectionChanged; - } - - internal void Shutdown() - { - if (m_HasDeserialized) - serializedPreferences = GetModule().SerializePreferences(); - } - - void OnDestroy() - { - s_Instance = null; - foreach (var nested in m_NestedModules.Values) - { - nested.OnDestroy(); - } - } - - void Update() - { - GetNestedModule().UpdateCamera(); - - Rays.UpdateRaycasts(); - - GetNestedModule().UpdateDefaultProxyRays(); - - GetNestedModule().UpdateDirectSelection(); - - GetModule().UpdateKeyboardMallets(); - - GetModule().ProcessInput(); - - GetNestedModule().UpdateMenuVisibilities(); - - GetNestedModule().UpdateManipulatorVisibilites(); - } - - void ProcessInput(HashSet processedInputs, ConsumeControlDelegate consumeControl) - { - GetNestedModule().UpdateMiniWorlds(); - - foreach (var deviceData in m_DeviceData) - { - if (!deviceData.proxy.active) - continue; - - foreach (var toolData in deviceData.toolData) - { - var process = toolData.tool as IProcessInput; - if (process != null && ((MonoBehaviour)toolData.tool).enabled - && processedInputs.Add(process)) // Only process inputs for an instance of a tool once (e.g. two-handed tools) - process.ProcessInput(toolData.input, consumeControl); - } - } - } - - T GetModule() where T : MonoBehaviour - { - MonoBehaviour module; - m_Modules.TryGetValue(typeof(T), out module); - return (T)module; - } - - T AddModule() where T : MonoBehaviour - { - MonoBehaviour module; - var type = typeof(T); - if (!m_Modules.TryGetValue(type, out module)) - { - module = ObjectUtils.AddComponent(gameObject); - m_Modules.Add(type, module); - - foreach (var nested in m_NestedModules.Values) - { - var lateBinding = nested as ILateBindInterfaceMethods; - if (lateBinding != null) - lateBinding.LateBindInterfaceMethods((T)module); - } - - this.ConnectInterfaces(module); - m_Interfaces.AttachInterfaceConnectors(module); - } - - return (T)module; - } - - T GetNestedModule() where T : Nested - { - return (T)m_NestedModules[typeof(T)]; - } - - Nested AddNestedModule(Type type) - { - Nested nested; - if (!m_NestedModules.TryGetValue(type, out nested)) - { - nested = (Nested)Activator.CreateInstance(type); - m_NestedModules.Add(type, nested); - - if (m_Interfaces != null) - { - this.ConnectInterfaces(nested); - m_Interfaces.AttachInterfaceConnectors(nested); - } - } - - return nested; - } - - void LateBindNestedModules(IEnumerable types) - { - foreach (var type in types) - { - var lateBindings = type.GetInterfaces().Where(i => - i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ILateBindInterfaceMethods<>)); - - Nested nestedModule; - if (m_NestedModules.TryGetValue(type, out nestedModule)) - { - foreach (var lateBinding in lateBindings) - { - var dependencyType = lateBinding.GetGenericArguments().First(); - - Nested dependency; - if (m_NestedModules.TryGetValue(dependencyType, out dependency)) - { - var map = type.GetInterfaceMap(lateBinding); - if (map.InterfaceMethods.Length == 1) - { - var tm = map.TargetMethods[0]; - tm.Invoke(nestedModule, new[] { dependency }); - } - } - } - } - } - } - - void SetHideFlags(HideFlags hideFlags) - { - ObjectUtils.hideFlags = hideFlags; - - foreach (var manager in Resources.FindObjectsOfTypeAll()) - { - manager.gameObject.hideFlags = hideFlags; - } - - foreach (var manager in Resources.FindObjectsOfTypeAll()) - { - manager.gameObject.hideFlags = hideFlags; - } - - foreach (var child in GetComponentsInChildren(true)) - { - child.gameObject.hideFlags = hideFlags; - } - - EditorApplication.DirtyHierarchyWindowSorting(); // Otherwise objects aren't shown/hidden in hierarchy window - } - - [PreferenceItem("EditorVR")] - static void PreferencesGUI() - { - EditorGUILayout.BeginVertical(); - EditorGUILayout.Space(); - - // Show EditorVR GameObjects - { - string title = "Show EditorVR GameObjects"; - string tooltip = "Normally, EditorVR GameObjects are hidden in the Hierarchy. Would you like to show them?"; - - EditorGUI.BeginChangeCheck(); - showGameObjects = EditorGUILayout.Toggle(new GUIContent(title, tooltip), showGameObjects); - if (EditorGUI.EndChangeCheck() && s_Instance) - s_Instance.SetHideFlags(defaultHideFlags); - } - - // Preserve Layout - { - string title = "Preserve Layout"; - string tooltip = "Check this to preserve your layout and location in EditorVR"; - preserveLayout = EditorGUILayout.Toggle(new GUIContent(title, tooltip), preserveLayout); - } - - GUILayout.FlexibleSpace(); - if (GUILayout.Button("Reset to Defaults", GUILayout.Width(140))) - ResetPreferences(); - - EditorGUILayout.EndVertical(); - } - -#if !INCLUDE_TEXT_MESH_PRO - static EditorVR() - { - Debug.LogWarning("EditorVR requires TextMesh Pro. Please go to the Asset Store and download/import Text Mesh Pro."); - } -#endif - } -#else - internal class NoEditorVR - { - const string k_ShowCustomEditorWarning = "EditorVR.ShowCustomEditorWarning"; - - static NoEditorVR() - { - if (EditorPrefs.GetBool(k_ShowCustomEditorWarning, true)) - { - var message = "EditorVR requires Unity 2017.2 or above."; - var result = EditorUtility.DisplayDialogComplex("Update Unity", message, "Download", "Ignore", "Remind Me Again"); - switch (result) - { - case 0: - Application.OpenURL("https://unity3d.com/get-unity/download"); - break; - case 1: - EditorPrefs.SetBool(k_ShowCustomEditorWarning, false); - break; - case 2: - Debug.Log("" + message + ""); - break; - } - } - } - } -#endif -} -#endif +#if UNITY_EDITOR +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor.Experimental.EditorVR; +using UnityEditor.Experimental.EditorVR.Extensions; +using UnityEditor.Experimental.EditorVR.Modules; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; +using UnityEngine.InputNew; + +[assembly: OptionalDependency("PolyToolkit.PolyApi", "INCLUDE_POLY_TOOLKIT")] +[assembly: OptionalDependency("UnityEngine.DrivenRectTransformTracker+BlockUndoCCU", "UNDO_PATCH")] + +namespace UnityEditor.Experimental.EditorVR.Core +{ +#if UNITY_2017_2_OR_NEWER + [InitializeOnLoad] + [RequiresTag(k_VRPlayerTag)] + sealed partial class EditorVR : MonoBehaviour, IConnectInterfaces + { + const string k_ShowGameObjects = "EditorVR.ShowGameObjects"; + const string k_PreserveLayout = "EditorVR.PreserveLayout"; + const string k_SerializedPreferences = "EditorVR.SerializedPreferences"; + const string k_VRPlayerTag = "VRPlayer"; + + Dictionary m_NestedModules = new Dictionary(); + Dictionary m_Modules = new Dictionary(); + + Interfaces m_Interfaces; + Type[] m_DefaultTools; + + event Action selectionChanged; + + readonly List m_DeviceData = new List(); + + bool m_HasDeserialized; + + static bool s_IsInitialized; + + static EditorVR s_Instance; + + static HideFlags defaultHideFlags + { + get { return showGameObjects ? HideFlags.DontSave : HideFlags.HideAndDontSave; } + } + + static bool showGameObjects + { + get { return EditorPrefs.GetBool(k_ShowGameObjects, false); } + set { EditorPrefs.SetBool(k_ShowGameObjects, value); } + } + + static bool preserveLayout + { + get { return EditorPrefs.GetBool(k_PreserveLayout, true); } + set { EditorPrefs.SetBool(k_PreserveLayout, value); } + } + + internal static string serializedPreferences + { + get { return EditorPrefs.GetString(k_SerializedPreferences, string.Empty); } + set { EditorPrefs.SetString(k_SerializedPreferences, value); } + } + + internal static Type[] defaultTools { get; set; } + + class DeviceData + { + public IProxy proxy; + public InputDevice inputDevice; + public Node node; + public Transform rayOrigin; + public readonly Stack toolData = new Stack(); + public IMainMenu mainMenu; + public ITool currentTool; + public IMenu customMenu; + public IToolsMenu toolsMenu; + public readonly List alternateMenus = new List(); + public IAlternateMenu alternateMenu; + public readonly Dictionary menuHideData = new Dictionary(); + } + + class Nested + { + public static EditorVR evr { protected get; set; } + + internal virtual void OnDestroy() { } + } + + static void ResetPreferences() + { + EditorPrefs.DeleteKey(k_ShowGameObjects); + EditorPrefs.DeleteKey(k_PreserveLayout); + EditorPrefs.DeleteKey(k_SerializedPreferences); + } + + // Code from the previous static constructor moved here to allow for testability + static void HandleInitialization() + { + if (!s_IsInitialized) + { + s_IsInitialized = true; + + if (!PlayerSettings.virtualRealitySupported) + Debug.Log("EditorVR requires VR support. Please check Virtual Reality Supported in Edit->Project Settings->Player->Other Settings"); + +#if !ENABLE_OVR_INPUT && !ENABLE_STEAMVR_INPUT && !ENABLE_SIXENSE_INPUT + Debug.Log("EditorVR requires at least one partner (e.g. Oculus, Vive) SDK to be installed for input. You can download these from the Asset Store or from the partner's website"); +#endif + } + // Add EVR tags and layers if they don't exist + var tags = TagManager.GetRequiredTags(); + var layers = TagManager.GetRequiredLayers(); + + foreach (var tag in tags) + { + TagManager.AddTag(tag); + } + + foreach (var layer in layers) + { + TagManager.AddLayer(layer); + } + } + + void Awake() + { +#if UNDO_PATCH + DrivenRectTransformTracker.BlockUndo = true; +#endif + s_Instance = this; // Used only by PreferencesGUI + Nested.evr = this; // Set this once for the convenience of all nested classes + m_DefaultTools = defaultTools; + SetHideFlags(defaultHideFlags); + ClearDeveloperConsoleIfNecessary(); + HandleInitialization(); + + m_Interfaces = (Interfaces)AddNestedModule(typeof(Interfaces)); + AddModule(); // Added here in case any nested modules have preference serialization + AddNestedModule(typeof(SerializedPreferencesModuleConnector)); + + var nestedClassTypes = ObjectUtils.GetExtensionsOfClass(typeof(Nested)); + foreach (var type in nestedClassTypes) + { + AddNestedModule(type); + } + LateBindNestedModules(nestedClassTypes); + + AddModule(); + AddModule(); + + var viewer = GetNestedModule(); + viewer.preserveCameraRig = preserveLayout; + viewer.InitializeCamera(); + + var deviceInputModule = AddModule(); + deviceInputModule.InitializePlayerHandle(); + deviceInputModule.CreateDefaultActionMapInputs(); + deviceInputModule.processInput = ProcessInput; + deviceInputModule.updatePlayerHandleMaps = Tools.UpdatePlayerHandleMaps; + deviceInputModule.inputDeviceForRayOrigin = rayOrigin => + (from deviceData in m_DeviceData + where deviceData.rayOrigin == rayOrigin + select deviceData.inputDevice).FirstOrDefault(); + + GetNestedModule().Initialize(); + + AddModule(); + + var multipleRayInputModule = GetModule(); + + var dragAndDropModule = AddModule(); + multipleRayInputModule.rayEntered += dragAndDropModule.OnRayEntered; + multipleRayInputModule.rayExited += dragAndDropModule.OnRayExited; + multipleRayInputModule.dragStarted += dragAndDropModule.OnDragStarted; + multipleRayInputModule.dragEnded += dragAndDropModule.OnDragEnded; + + var tooltipModule = AddModule(); + this.ConnectInterfaces(tooltipModule); + multipleRayInputModule.rayEntered += tooltipModule.OnRayEntered; + multipleRayInputModule.rayHovering += tooltipModule.OnRayHovering; + multipleRayInputModule.rayExited += tooltipModule.OnRayExited; + + AddModule(); + AddModule(); + + var lockModule = AddModule(); + lockModule.updateAlternateMenu = (rayOrigin, o) => Menus.SetAlternateMenuVisibility(rayOrigin, o != null); + + AddModule(); + + var spatialHashModule = AddModule(); + spatialHashModule.shouldExcludeObject = go => go.GetComponentInParent(); + spatialHashModule.Setup(); + + var intersectionModule = AddModule(); + this.ConnectInterfaces(intersectionModule); + intersectionModule.Setup(spatialHashModule.spatialHash); + // TODO: Support module dependencies via ConnectInterfaces + GetNestedModule().ignoreList = intersectionModule.standardIgnoreList; + + AddModule(); + + var vacuumables = GetNestedModule(); + + var miniWorlds = GetNestedModule(); + var workspaceModule = AddModule(); + workspaceModule.preserveWorkspaces = preserveLayout; + workspaceModule.workspaceCreated += vacuumables.OnWorkspaceCreated; + workspaceModule.workspaceCreated += miniWorlds.OnWorkspaceCreated; + workspaceModule.workspaceCreated += workspace => { deviceInputModule.UpdatePlayerHandleMaps(); }; + workspaceModule.workspaceDestroyed += vacuumables.OnWorkspaceDestroyed; + workspaceModule.workspaceDestroyed += miniWorlds.OnWorkspaceDestroyed; + + UnityBrandColorScheme.sessionGradient = UnityBrandColorScheme.GetRandomCuratedLightGradient(); + UnityBrandColorScheme.saturatedSessionGradient = UnityBrandColorScheme.GetRandomCuratedGradient(); + + var sceneObjectModule = AddModule(); + sceneObjectModule.tryPlaceObject = (obj, targetScale) => + { + foreach (var miniWorld in miniWorlds.worlds) + { + if (!miniWorld.Contains(obj.position)) + continue; + + var referenceTransform = miniWorld.referenceTransform; + obj.transform.parent = null; + obj.position = referenceTransform.position + Vector3.Scale(miniWorld.miniWorldTransform.InverseTransformPoint(obj.position), miniWorld.referenceTransform.localScale); + obj.rotation = referenceTransform.rotation * Quaternion.Inverse(miniWorld.miniWorldTransform.rotation) * obj.rotation; + obj.localScale = Vector3.Scale(Vector3.Scale(obj.localScale, referenceTransform.localScale), miniWorld.miniWorldTransform.lossyScale.Inverse()); + + spatialHashModule.AddObject(obj.gameObject); + return true; + } + + return false; + }; + + AddModule(); + AddModule(); + AddModule(); + + AddModule(); + + AddModule(); + + //TODO: External module support (removes need for CCU in this instance) +#if INCLUDE_POLY_TOOLKIT + AddModule(); +#endif + + viewer.AddPlayerModel(); + + GetNestedModule().CreateAllProxies(); + + // In case we have anything selected at start, set up manipulators, inspector, etc. + EditorApplication.delayCall += OnSelectionChanged; + } + + IEnumerator Start() + { + var leftHandFound = false; + var rightHandFound = false; + + // Some components depend on both hands existing (e.g. MiniWorldWorkspace), so make sure they exist before restoring + while (!(leftHandFound && rightHandFound)) + { + Rays.ForEachProxyDevice(deviceData => + { + if (deviceData.node == Node.LeftHand) + leftHandFound = true; + + if (deviceData.node == Node.RightHand) + rightHandFound = true; + }); + + yield return null; + } + + var viewer = GetNestedModule(); + while (!viewer.hmdReady) + yield return null; + + GetModule().SetupWithPreferences(serializedPreferences); + m_HasDeserialized = true; + } + + static void ClearDeveloperConsoleIfNecessary() + { + var asm = Assembly.GetAssembly(typeof(Editor)); + var consoleWindowType = asm.GetType("UnityEditor.ConsoleWindow"); + + EditorWindow window = null; + foreach (var w in Resources.FindObjectsOfTypeAll()) + { + if (w.GetType() == consoleWindowType) + { + window = w; + break; + } + } + + if (window) + { + var consoleFlagsType = consoleWindowType.GetNestedType("ConsoleFlags", BindingFlags.NonPublic); + var names = Enum.GetNames(consoleFlagsType); + var values = Enum.GetValues(consoleFlagsType); + var clearOnPlayFlag = values.GetValue(Array.IndexOf(names, "ClearOnPlay")); + + var hasFlagMethod = consoleWindowType.GetMethod("HasFlag", BindingFlags.NonPublic | BindingFlags.Static); + var result = (bool)hasFlagMethod.Invoke(window, new[] { clearOnPlayFlag }); + + if (result) + { + var logEntries = asm.GetType("UnityEditor.LogEntries"); + var clearMethod = logEntries.GetMethod("Clear", BindingFlags.Static | BindingFlags.Public); + clearMethod.Invoke(null, null); + } + } + } + + void OnSelectionChanged() + { + if (selectionChanged != null) + selectionChanged(); + + Menus.UpdateAlternateMenuOnSelectionChanged(GetNestedModule().lastSelectionRayOrigin); + } + + void OnEnable() + { + Selection.selectionChanged += OnSelectionChanged; + } + + void OnDisable() + { + Selection.selectionChanged -= OnSelectionChanged; + } + + internal void Shutdown() + { + if (m_HasDeserialized) + serializedPreferences = GetModule().SerializePreferences(); + } + + void OnDestroy() + { + s_Instance = null; + foreach (var nested in m_NestedModules.Values) + { + nested.OnDestroy(); + } + +#if UNDO_PATCH + DrivenRectTransformTracker.BlockUndo = false; +#endif + } + + void Update() + { + GetNestedModule().UpdateCamera(); + + Rays.UpdateRaycasts(); + + GetNestedModule().UpdateDefaultProxyRays(); + + GetNestedModule().UpdateDirectSelection(); + + GetModule().UpdateKeyboardMallets(); + + GetModule().ProcessInput(); + + GetNestedModule().UpdateMenuVisibilities(); + + GetNestedModule().UpdateManipulatorVisibilites(); + } + + void ProcessInput(HashSet processedInputs, ConsumeControlDelegate consumeControl) + { + GetNestedModule().UpdateMiniWorlds(); + + foreach (var deviceData in m_DeviceData) + { + if (!deviceData.proxy.active) + continue; + + foreach (var toolData in deviceData.toolData) + { + var process = toolData.tool as IProcessInput; + if (process != null && ((MonoBehaviour)toolData.tool).enabled + && processedInputs.Add(process)) // Only process inputs for an instance of a tool once (e.g. two-handed tools) + process.ProcessInput(toolData.input, consumeControl); + } + } + } + + T GetModule() where T : MonoBehaviour + { + MonoBehaviour module; + m_Modules.TryGetValue(typeof(T), out module); + return (T)module; + } + + T AddModule() where T : MonoBehaviour + { + MonoBehaviour module; + var type = typeof(T); + if (!m_Modules.TryGetValue(type, out module)) + { + module = ObjectUtils.AddComponent(gameObject); + m_Modules.Add(type, module); + + foreach (var nested in m_NestedModules.Values) + { + var lateBinding = nested as ILateBindInterfaceMethods; + if (lateBinding != null) + lateBinding.LateBindInterfaceMethods((T)module); + } + + this.ConnectInterfaces(module); + m_Interfaces.AttachInterfaceConnectors(module); + } + + return (T)module; + } + + T GetNestedModule() where T : Nested + { + return (T)m_NestedModules[typeof(T)]; + } + + Nested AddNestedModule(Type type) + { + Nested nested; + if (!m_NestedModules.TryGetValue(type, out nested)) + { + nested = (Nested)Activator.CreateInstance(type); + m_NestedModules.Add(type, nested); + + if (m_Interfaces != null) + { + this.ConnectInterfaces(nested); + m_Interfaces.AttachInterfaceConnectors(nested); + } + } + + return nested; + } + + void LateBindNestedModules(IEnumerable types) + { + foreach (var type in types) + { + var lateBindings = type.GetInterfaces().Where(i => + i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ILateBindInterfaceMethods<>)); + + Nested nestedModule; + if (m_NestedModules.TryGetValue(type, out nestedModule)) + { + foreach (var lateBinding in lateBindings) + { + var dependencyType = lateBinding.GetGenericArguments().First(); + + Nested dependency; + if (m_NestedModules.TryGetValue(dependencyType, out dependency)) + { + var map = type.GetInterfaceMap(lateBinding); + if (map.InterfaceMethods.Length == 1) + { + var tm = map.TargetMethods[0]; + tm.Invoke(nestedModule, new[] { dependency }); + } + } + } + } + } + } + + void SetHideFlags(HideFlags hideFlags) + { + ObjectUtils.hideFlags = hideFlags; + + foreach (var manager in Resources.FindObjectsOfTypeAll()) + { + manager.gameObject.hideFlags = hideFlags; + } + + foreach (var manager in Resources.FindObjectsOfTypeAll()) + { + manager.gameObject.hideFlags = hideFlags; + } + + foreach (var child in GetComponentsInChildren(true)) + { + child.gameObject.hideFlags = hideFlags; + } + + EditorApplication.DirtyHierarchyWindowSorting(); // Otherwise objects aren't shown/hidden in hierarchy window + } + + [PreferenceItem("EditorVR")] + static void PreferencesGUI() + { + EditorGUILayout.BeginVertical(); + EditorGUILayout.Space(); + + // Show EditorVR GameObjects + { + string title = "Show EditorVR GameObjects"; + string tooltip = "Normally, EditorVR GameObjects are hidden in the Hierarchy. Would you like to show them?"; + + EditorGUI.BeginChangeCheck(); + showGameObjects = EditorGUILayout.Toggle(new GUIContent(title, tooltip), showGameObjects); + if (EditorGUI.EndChangeCheck() && s_Instance) + s_Instance.SetHideFlags(defaultHideFlags); + } + + // Preserve Layout + { + string title = "Preserve Layout"; + string tooltip = "Check this to preserve your layout and location in EditorVR"; + preserveLayout = EditorGUILayout.Toggle(new GUIContent(title, tooltip), preserveLayout); + } + + GUILayout.FlexibleSpace(); + if (GUILayout.Button("Reset to Defaults", GUILayout.Width(140))) + ResetPreferences(); + + EditorGUILayout.EndVertical(); + } + +#if !INCLUDE_TEXT_MESH_PRO + static EditorVR() + { + Debug.LogWarning("EditorVR requires TextMesh Pro. Please go to the Asset Store and download/import Text Mesh Pro."); + } +#endif + } +#else + internal class NoEditorVR + { + const string k_ShowCustomEditorWarning = "EditorVR.ShowCustomEditorWarning"; + + static NoEditorVR() + { + if (EditorPrefs.GetBool(k_ShowCustomEditorWarning, true)) + { + var message = "EditorVR requires Unity 2017.2 or above."; + var result = EditorUtility.DisplayDialogComplex("Update Unity", message, "Download", "Ignore", "Remind Me Again"); + switch (result) + { + case 0: + Application.OpenURL("https://unity3d.com/get-unity/download"); + break; + case 1: + EditorPrefs.SetBool(k_ShowCustomEditorWarning, false); + break; + case 2: + Debug.Log("" + message + ""); + break; + } + } + } + } +#endif +} +#endif diff --git a/Scripts/Core/InterfaceConnectors/ActionsModuleConnector.cs b/Scripts/Core/InterfaceConnectors/ActionsModuleConnector.cs index 47cd17466..40981142a 100644 --- a/Scripts/Core/InterfaceConnectors/ActionsModuleConnector.cs +++ b/Scripts/Core/InterfaceConnectors/ActionsModuleConnector.cs @@ -1,62 +1,65 @@ -#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER -using UnityEditor.Experimental.EditorVR.Modules; - -namespace UnityEditor.Experimental.EditorVR.Core -{ - partial class EditorVR - { - class ActionsModuleConnector : Nested, IInterfaceConnector - { - public void ConnectInterface(object target, object userData = null) - { - var actionsModule = evr.GetModule(); - if (actionsModule) - { - var menuActions = actionsModule.menuActions; - - var toolActions = target as IActions; - if (toolActions != null) - { - // Delay connecting actions to allow tool / module to initialize first - EditorApplication.delayCall += () => - { - var actions = toolActions.actions; - if (actions != null) - { - foreach (var action in actions) - { - var actionMenuData = new ActionMenuData() - { - name = action.GetType().Name, - sectionName = ActionMenuItemAttribute.DefaultActionSectionName, - priority = int.MaxValue, - action = action, - }; - menuActions.Add(actionMenuData); - } - Menus.UpdateAlternateMenuActions(); - } - }; - } - - var alternateMenu = target as IAlternateMenu; - if (alternateMenu != null) - alternateMenu.menuActions = menuActions; - } - } - - public void DisconnectInterface(object target, object userData = null) - { - var toolActions = target as IActions; - if (toolActions != null) - { - var evrActionsModule = evr.GetModule(); - - evrActionsModule.RemoveActions(toolActions.actions); - Menus.UpdateAlternateMenuActions(); - } - } - } - } -} -#endif +#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER +using UnityEditor.Experimental.EditorVR.Modules; + +namespace UnityEditor.Experimental.EditorVR.Core +{ + partial class EditorVR + { + class ActionsModuleConnector : Nested, IInterfaceConnector + { + public void ConnectInterface(object target, object userData = null) + { + var actionsModule = evr.GetModule(); + if (actionsModule) + { + var menuActions = actionsModule.menuActions; + + var toolActions = target as IActions; + if (toolActions != null) + { + // Delay connecting actions to allow tool / module to initialize first + EditorApplication.delayCall += () => + { + var actions = toolActions.actions; + if (actions != null) + { + foreach (var action in actions) + { + var actionMenuData = new ActionMenuData() + { + name = action.GetType().Name, + sectionName = ActionMenuItemAttribute.DefaultActionSectionName, + priority = int.MaxValue, + action = action, + }; + menuActions.Add(actionMenuData); + } + actionsModule.UpdateAlternateMenuActions(); + } + }; + } + + var actionsMenu = target as IActionsMenu; + if (actionsMenu != null) + { + actionsMenu.menuActions = menuActions; + actionsModule.AddActionsMenu(actionsMenu); + } + } + } + + public void DisconnectInterface(object target, object userData = null) + { + var toolActions = target as IActions; + if (toolActions != null) + { + var evrActionsModule = evr.GetModule(); + + evrActionsModule.RemoveActions(toolActions.actions); + evrActionsModule.UpdateAlternateMenuActions(); + } + } + } + } +} +#endif diff --git a/Scripts/Core/VRView.cs b/Scripts/Core/VRView.cs index 3c8c2bc1f..9a004b457 100644 --- a/Scripts/Core/VRView.cs +++ b/Scripts/Core/VRView.cs @@ -1,10 +1,11 @@ #if UNITY_EDITOR using System; -using UnityEngine; -using UnityEngine.Assertions; using System.Collections; -using UnityEditor.Experimental.EditorVR.Helpers; using System.Reflection; +using UnityEditor.Experimental.EditorVR.Helpers; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; +using UnityEngine.Assertions; using UnityEngine.XR; #if ENABLE_STEAMVR_INPUT @@ -18,6 +19,10 @@ sealed class VRView : EditorWindow public const float HeadHeight = 1.7f; const string k_ShowDeviceView = "VRView.ShowDeviceView"; const string k_UseCustomPreviewCamera = "VRView.UseCustomPreviewCamera"; + const string k_CameraName = "VRCamera"; + + static Camera s_ExistingSceneMainCamera; + static bool s_ExistingSceneMainCameraEnabledState; DrawCameraMode m_RenderMode = DrawCameraMode.Textured; @@ -54,7 +59,7 @@ public static Camera customPreviewCamera bool m_UseCustomPreviewCamera; Rect m_ToggleDeviceViewRect = new Rect(0, 0, 0, 20); // Width will be set based on window size - Rect m_PresentationCameraRect = new Rect(0, 0, 0, 20); // Y position and width will be set based on window size + Rect m_PresentationCameraRect = new Rect(0, 0, 160, 20); // Y position and width will be set based on window size public static Transform cameraRig { @@ -111,8 +116,8 @@ public static Vector3 headCenteredOrigin public static event Action viewEnabled; public static event Action viewDisabled; - public static event Action beforeOnGUI; - public static event Action afterOnGUI; + public static event Action beforeOnGUI; + public static event Action afterOnGUI; public static event Action hmdStatusChange; public Rect guiRect { get; private set; } @@ -134,18 +139,53 @@ public void OnEnable() autoRepaintOnSceneChange = true; s_ActiveView = this; + const float nearClipPlane = 0.01f; + const float farClipPlane = 1000f; + + s_ExistingSceneMainCamera = Camera.main; + // TODO: Copy camera settings when changing contexts + if (EditingContextManager.defaultContext.copyExistingCameraSettings && s_ExistingSceneMainCamera && s_ExistingSceneMainCamera.enabled) + { + GameObject cameraGO = EditorUtility.CreateGameObjectWithHideFlags(k_CameraName, HideFlags.HideAndDontSave); + m_Camera = ObjectUtils.CopyComponent(s_ExistingSceneMainCamera, cameraGO); + + if (m_Camera.nearClipPlane > nearClipPlane) + { + Debug.LogWarning("Copying settings from scene camera that is tagged 'MainCamera'." + Environment.NewLine + + " Clipping issues may occur with NearClipPlane values is greater than " + nearClipPlane); + + m_Camera.nearClipPlane = nearClipPlane; + } + + // TODO: Support multiple cameras + if (m_Camera.clearFlags == CameraClearFlags.Nothing) + m_Camera.clearFlags = CameraClearFlags.SolidColor; + + m_Camera.stereoTargetEye = StereoTargetEyeMask.Both; + // Force HDR on because of a bug in the mirror view + m_Camera.allowHDR = true; + } + else + { + GameObject cameraGO = EditorUtility.CreateGameObjectWithHideFlags(k_CameraName, HideFlags.HideAndDontSave, typeof(Camera)); + m_Camera = cameraGO.GetComponent(); + + m_Camera.nearClipPlane = nearClipPlane; + m_Camera.farClipPlane = farClipPlane; + } + + if (s_ExistingSceneMainCamera) + { + s_ExistingSceneMainCameraEnabledState = s_ExistingSceneMainCamera.enabled; + s_ExistingSceneMainCamera.enabled = false; // Disable existing MainCamera in the scene + } - GameObject cameraGO = EditorUtility.CreateGameObjectWithHideFlags("VRCamera", HideFlags.HideAndDontSave, typeof(Camera)); - m_Camera = cameraGO.GetComponent(); - m_Camera.useOcclusionCulling = false; m_Camera.enabled = false; m_Camera.cameraType = CameraType.VR; - + m_Camera.useOcclusionCulling = false; GameObject rigGO = EditorUtility.CreateGameObjectWithHideFlags("VRCameraRig", HideFlags.HideAndDontSave, typeof(EditorMonoBehaviour)); m_CameraRig = rigGO.transform; m_Camera.transform.parent = m_CameraRig; - m_Camera.nearClipPlane = 0.01f; - m_Camera.farClipPlane = 1000f; m_CameraRig.position = headCenteredOrigin; m_CameraRig.rotation = Quaternion.identity; @@ -186,6 +226,9 @@ public void OnDisable() Assert.IsNotNull(s_ActiveView, "EditorXR should have an active view"); s_ActiveView = null; + + if (s_ExistingSceneMainCamera) + s_ExistingSceneMainCamera.enabled = s_ExistingSceneMainCameraEnabledState; } void UpdateCameraTransform() @@ -279,7 +322,6 @@ void OnGUI() m_ToggleDeviceViewRect.width = width; m_PresentationCameraRect.y = height - m_PresentationCameraRect.height; - m_PresentationCameraRect.width = width; if (GUI.Button(m_ToggleDeviceViewRect, "Toggle Device View", EditorStyles.toolbarButton)) m_ShowDeviceView = !m_ShowDeviceView; diff --git a/Scripts/Helpers/VRSmoothCamera.cs b/Scripts/Helpers/VRSmoothCamera.cs index b3d05d7b0..e3abbb491 100644 --- a/Scripts/Helpers/VRSmoothCamera.cs +++ b/Scripts/Helpers/VRSmoothCamera.cs @@ -79,6 +79,16 @@ void Start() m_Rotation = transform.localRotation; } + void OnEnable() + { + // Snap camera to starting position + if (m_VRCamera) + { + m_Rotation = m_VRCamera.transform.localRotation; + m_Position = m_VRCamera.transform.localPosition; + } + } + void LateUpdate() { m_SmoothCamera.CopyFrom(m_VRCamera); // This copies the transform as well diff --git a/Scripts/Interfaces/Entity/IAlternateMenu.cs b/Scripts/Interfaces/Entity/IAlternateMenu.cs index 329f94d1d..1580f25d9 100644 --- a/Scripts/Interfaces/Entity/IAlternateMenu.cs +++ b/Scripts/Interfaces/Entity/IAlternateMenu.cs @@ -1,18 +1,14 @@ -#if UNITY_EDITOR -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.EditorVR -{ - /// - /// An alternate menu that shows on device proxies - /// - public interface IAlternateMenu : IMenu, IUsesMenuActions, IUsesRayOrigin - { - /// - /// Delegate called when any item was selected in the alternate menu - /// - event Action itemWasSelected; - } -} -#endif +#if UNITY_EDITOR +using System; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR +{ + /// + /// An alternate menu that shows on device proxies + /// + public interface IAlternateMenu : IMenu, IUsesRayOrigin + { + } +} +#endif diff --git a/Scripts/Interfaces/Entity/IEditingContext.cs b/Scripts/Interfaces/Entity/IEditingContext.cs index c95aeb6f4..13273843f 100644 --- a/Scripts/Interfaces/Entity/IEditingContext.cs +++ b/Scripts/Interfaces/Entity/IEditingContext.cs @@ -1,4 +1,6 @@ #if UNITY_EDITOR +using UnityEditor.Experimental.EditorVR.Core; + namespace UnityEditor.Experimental.EditorVR { /// @@ -12,6 +14,16 @@ public interface IEditingContext /// string name { get; } + /// + /// Bool denotes that the scene camera's (component) values should be cloned on the XR runtime camera + /// + bool copyExistingCameraSettings { get; } + + /// + /// Bool denotes that the EditorVR instance exists, having already been created in Setup() + /// + bool instanceExists { get; } + /// /// Perform one-time setup for the context when pushed to the stack. /// diff --git a/Scripts/Interfaces/Entity/IMainMenu.cs b/Scripts/Interfaces/Entity/IMainMenu.cs index f0f540d3b..da4c94b13 100644 --- a/Scripts/Interfaces/Entity/IMainMenu.cs +++ b/Scripts/Interfaces/Entity/IMainMenu.cs @@ -1,68 +1,68 @@ -#if UNITY_EDITOR -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.EditorVR -{ - /// - /// The main menu that can be shown on device proxies - /// - public interface IMainMenu : IMenu, IUsesMenuActions, ISelectTool, IPreviewInToolsMenuButton - { - /// - /// The menu tools that will populate the menu - /// - List menuTools { set; } - - /// - /// The workspaces that are selectable from the menu - /// - List menuWorkspaces { set; } - - /// - /// The types which provide a settings menu - /// - Dictionary, ISettingsMenuProvider> settingsMenuProviders { set; } - - /// - /// The types which provide a settings menu item - /// - Dictionary, ISettingsMenuItemProvider> settingsMenuItemProviders { set; } - - /// - /// The ray origin that spawned the menu and will be used for node-specific operations (e.g. selecting a tool) - /// - Transform targetRayOrigin { set; } - - /// - /// Does this menu have focus? - /// - bool focus { get; } - - /// - /// Add a settings menu to this menu - /// - /// The object providing the settings menu - void AddSettingsMenu(ISettingsMenuProvider provider); - - /// - /// Remove a settings menu from this menu - /// - /// The object which provided the settings menu - void RemoveSettingsMenu(ISettingsMenuProvider provider); - - /// - /// Add a settings menu item to this menu - /// - /// The object providing the settings menu item - void AddSettingsMenuItem(ISettingsMenuItemProvider provider); - - /// - /// Remove a settings menu item from this menu - /// - /// The object which provided the settings menu item - void RemoveSettingsMenuItem(ISettingsMenuItemProvider provider); - } -} -#endif +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR +{ + /// + /// The main menu that can be shown on device proxies + /// + public interface IMainMenu : IMenu, ISelectTool, IPreviewInToolsMenuButton + { + /// + /// The menu tools that will populate the menu + /// + List menuTools { set; } + + /// + /// The workspaces that are selectable from the menu + /// + List menuWorkspaces { set; } + + /// + /// The types which provide a settings menu + /// + Dictionary, ISettingsMenuProvider> settingsMenuProviders { set; } + + /// + /// The types which provide a settings menu item + /// + Dictionary, ISettingsMenuItemProvider> settingsMenuItemProviders { set; } + + /// + /// The ray origin that spawned the menu and will be used for node-specific operations (e.g. selecting a tool) + /// + Transform targetRayOrigin { set; } + + /// + /// Does this menu have focus? + /// + bool focus { get; } + + /// + /// Add a settings menu to this menu + /// + /// The object providing the settings menu + void AddSettingsMenu(ISettingsMenuProvider provider); + + /// + /// Remove a settings menu from this menu + /// + /// The object which provided the settings menu + void RemoveSettingsMenu(ISettingsMenuProvider provider); + + /// + /// Add a settings menu item to this menu + /// + /// The object providing the settings menu item + void AddSettingsMenuItem(ISettingsMenuItemProvider provider); + + /// + /// Remove a settings menu item from this menu + /// + /// The object which provided the settings menu item + void RemoveSettingsMenuItem(ISettingsMenuItemProvider provider); + } +} +#endif diff --git a/Scripts/Interfaces/Entity/IMenu.cs b/Scripts/Interfaces/Entity/IMenu.cs index a466e13c6..a43eaa7a0 100644 --- a/Scripts/Interfaces/Entity/IMenu.cs +++ b/Scripts/Interfaces/Entity/IMenu.cs @@ -1,33 +1,35 @@ -#if UNITY_EDITOR -using UnityEditor.Experimental.EditorVR.Menus; -using UnityEngine; - -namespace UnityEditor.Experimental.EditorVR -{ - /// - /// Declares a class as a system-level menu - /// - public interface IMenu - { - /// - /// Visibility state of this menu - /// - MenuHideFlags menuHideFlags { get; set; } - - /// - /// GameObject that this component is attached to - /// - GameObject gameObject { get; } - - /// - /// Root GameObject for visible menu content - /// - GameObject menuContent { get; } - - /// - /// The local bounds of this menu - /// - Bounds localBounds { get; } - } -} -#endif +#if UNITY_EDITOR +using UnityEditor.Experimental.EditorVR.Menus; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR +{ + /// + /// Declares a class as a system-level menu + /// + public interface IMenu + { + /// + /// Visibility state of this menu + /// + MenuHideFlags menuHideFlags { get; set; } + + /// + /// GameObject that this component is attached to + /// + GameObject gameObject { get; } + + /// + /// Root GameObject for visible menu content + /// + GameObject menuContent { get; } + + /// + /// The local bounds of this menu + /// + Bounds localBounds { get; } + + int priority { get; } + } +} +#endif diff --git a/Scripts/Interfaces/FunctionalityInjection/IUsesMenuActions.cs b/Scripts/Interfaces/FunctionalityInjection/IActionsMenu.cs similarity index 57% rename from Scripts/Interfaces/FunctionalityInjection/IUsesMenuActions.cs rename to Scripts/Interfaces/FunctionalityInjection/IActionsMenu.cs index 4a73733b0..74ccb196a 100644 --- a/Scripts/Interfaces/FunctionalityInjection/IUsesMenuActions.cs +++ b/Scripts/Interfaces/FunctionalityInjection/IActionsMenu.cs @@ -1,17 +1,24 @@ -#if UNITY_EDITOR -using System.Collections.Generic; - -namespace UnityEditor.Experimental.EditorVR -{ - /// - /// Decorates a class that wants to receive menu actions - /// - public interface IUsesMenuActions - { - /// - /// Collection of actions that can be performed - /// - List menuActions { set; } - } -} -#endif +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR +{ + /// + /// Decorates a class that wants to receive menu actions + /// + public interface IActionsMenu : IMenu + { + /// + /// Collection of actions that can be performed + /// + List menuActions { set; } + + /// + /// Delegate called when any item was selected in the alternate menu + /// + event Action itemWasSelected; + } +} +#endif diff --git a/Scripts/Interfaces/FunctionalityInjection/IUsesMenuActions.cs.meta b/Scripts/Interfaces/FunctionalityInjection/IActionsMenu.cs.meta similarity index 100% rename from Scripts/Interfaces/FunctionalityInjection/IUsesMenuActions.cs.meta rename to Scripts/Interfaces/FunctionalityInjection/IActionsMenu.cs.meta diff --git a/Scripts/Interfaces/FunctionalityInjection/IInstantiateMenuUI.cs b/Scripts/Interfaces/FunctionalityInjection/IInstantiateMenuUI.cs index da1edb7f0..204d450de 100644 --- a/Scripts/Interfaces/FunctionalityInjection/IInstantiateMenuUI.cs +++ b/Scripts/Interfaces/FunctionalityInjection/IInstantiateMenuUI.cs @@ -6,7 +6,8 @@ namespace UnityEditor.Experimental.EditorVR { /// /// Provides custom menu instantiation - /// public interface IInstantiateMenuUI + /// + public interface IInstantiateMenuUI { } diff --git a/Scripts/Interfaces/FunctionalityInjection/IRequestFeedback.cs b/Scripts/Interfaces/FunctionalityInjection/IRequestFeedback.cs index 73163487f..779ebbb5c 100644 --- a/Scripts/Interfaces/FunctionalityInjection/IRequestFeedback.cs +++ b/Scripts/Interfaces/FunctionalityInjection/IRequestFeedback.cs @@ -48,6 +48,7 @@ public static void ClearFeedbackRequests(this IRequestFeedback obj) /// /// Get a pooled FeedbackRequest object from the system /// + /// The type of request object desired public static FeedbackRequest GetFeedbackRequestObject(this IRequestFeedback obj, Type type) { return getFeedbackRequestObject(type); diff --git a/Scripts/Modules/ActionsModule.cs b/Scripts/Modules/ActionsModule.cs index 6eff8c245..c0c39fa69 100644 --- a/Scripts/Modules/ActionsModule.cs +++ b/Scripts/Modules/ActionsModule.cs @@ -1,63 +1,76 @@ -#if UNITY_EDITOR -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; - -namespace UnityEditor.Experimental.EditorVR.Modules -{ - sealed class ActionsModule : MonoBehaviour, IConnectInterfaces - { - public List menuActions { get { return m_MenuActions; } } - - List m_MenuActions = new List(); - List m_Actions; - - public void RemoveActions(List actions) - { - m_MenuActions.Clear(); - m_MenuActions.AddRange(m_MenuActions.Where(a => !actions.Contains(a.action))); - } - - void Start() - { - SpawnActions(); - } - - void SpawnActions() - { - IEnumerable actionTypes = ObjectUtils.GetImplementationsOfInterface(typeof(IAction)); - m_Actions = new List(); - foreach (Type actionType in actionTypes) - { - // Don't treat vanilla actions or tool actions as first class actions - if (actionType.IsNested || !typeof(MonoBehaviour).IsAssignableFrom(actionType)) - continue; - - var action = ObjectUtils.AddComponent(actionType, gameObject) as IAction; - var attribute = (ActionMenuItemAttribute)actionType.GetCustomAttributes(typeof(ActionMenuItemAttribute), false).FirstOrDefault(); - - this.ConnectInterfaces(action); - - if (attribute != null) - { - var actionMenuData = new ActionMenuData() - { - name = attribute.name, - sectionName = attribute.sectionName, - priority = attribute.priority, - action = action, - }; - - m_MenuActions.Add(actionMenuData); - } - - m_Actions.Add(action); - } - - m_MenuActions.Sort((x, y) => y.priority.CompareTo(x.priority)); - } - } -} -#endif +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR.Modules +{ + sealed class ActionsModule : MonoBehaviour, IConnectInterfaces + { + public List menuActions { get { return m_MenuActions; } } + + List m_MenuActions = new List(); + readonly List m_Actions = new List(); + readonly List m_ActionsMenus = new List(); + + public void RemoveActions(List actions) + { + m_MenuActions.Clear(); + m_MenuActions.AddRange(m_MenuActions.Where(a => !actions.Contains(a.action))); + } + + void Start() + { + SpawnActions(); + } + + void SpawnActions() + { + IEnumerable actionTypes = ObjectUtils.GetImplementationsOfInterface(typeof(IAction)); + foreach (Type actionType in actionTypes) + { + // Don't treat vanilla actions or tool actions as first class actions + if (actionType.IsNested || !typeof(MonoBehaviour).IsAssignableFrom(actionType)) + continue; + + var action = ObjectUtils.AddComponent(actionType, gameObject) as IAction; + var attribute = (ActionMenuItemAttribute)actionType.GetCustomAttributes(typeof(ActionMenuItemAttribute), false).FirstOrDefault(); + + this.ConnectInterfaces(action); + + if (attribute != null) + { + var actionMenuData = new ActionMenuData() + { + name = attribute.name, + sectionName = attribute.sectionName, + priority = attribute.priority, + action = action, + }; + + m_MenuActions.Add(actionMenuData); + } + + m_Actions.Add(action); + } + + m_MenuActions.Sort((x, y) => y.priority.CompareTo(x.priority)); + } + + public void AddActionsMenu(IActionsMenu actionsMenu) + { + m_ActionsMenus.Add(actionsMenu); + } + + internal void UpdateAlternateMenuActions() + { + foreach (var actionsMenu in m_ActionsMenus) + { + actionsMenu.menuActions = m_MenuActions; + } + } + } +} +#endif diff --git a/Scripts/Modules/FeedbackModule/FeedbackModule.cs b/Scripts/Modules/FeedbackModule/FeedbackModule.cs index e98ef4c69..2d96d7b83 100644 --- a/Scripts/Modules/FeedbackModule/FeedbackModule.cs +++ b/Scripts/Modules/FeedbackModule/FeedbackModule.cs @@ -1,11 +1,18 @@ #if UNITY_EDITOR using System; using System.Collections.Generic; +using UnityEditor.Experimental.EditorVR; using UnityEditor.Experimental.EditorVR.Core; using UnityEditor.Experimental.EditorVR.Handles; using UnityEngine; using UnityEngine.UI; +#if INCLUDE_TEXT_MESH_PRO +using TMPro; +#endif + +[assembly: OptionalDependency("TMPro.TextMeshProUGUI", "INCLUDE_TEXT_MESH_PRO")] + namespace UnityEditor.Experimental.EditorVR { public abstract class FeedbackRequest @@ -50,7 +57,9 @@ public GameObject settingsMenuItemInstance toggle.isOn = m_Preferences.enabled; m_Toggles.Add(toggle); - var label = value.GetComponentInChildren(); + +#if INCLUDE_TEXT_MESH_PRO + var label = value.GetComponentInChildren(); const string feedbackEnabled = "Feedback enabled"; const string feedbackDisabled = "Feedback disabled"; @@ -66,6 +75,7 @@ public GameObject settingsMenuItemInstance var handle = value.GetComponent(); handle.hoverStarted += (baseHandle, data) => { label.text = m_Preferences.enabled ? disableFeedback : enableFeedback; }; handle.hoverEnded += (baseHandle, data) => { label.text = m_Preferences.enabled ? feedbackEnabled : feedbackDisabled; }; +#endif } } diff --git a/Scripts/Modules/FeedbackModule/SettingsUI.prefab b/Scripts/Modules/FeedbackModule/SettingsUI.prefab index c6f8dd9d2..428a15cf7 100644 --- a/Scripts/Modules/FeedbackModule/SettingsUI.prefab +++ b/Scripts/Modules/FeedbackModule/SettingsUI.prefab @@ -20,7 +20,7 @@ GameObject: m_Component: - component: {fileID: 224171904768544026} - component: {fileID: 222812621535630740} - - component: {fileID: 114103337935952270} + - component: {fileID: 114454282082524566} m_Layer: 5 m_Name: Label m_TagString: Untagged @@ -80,39 +80,6 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!114 &114103337935952270 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1082264891174920} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 20 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 3 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Feedback enabled --- !u!114 &114126329478329400 MonoBehaviour: m_ObjectHideFlags: 1 @@ -152,6 +119,118 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_SelectionFlags: 3 +--- !u!114 &114454282082524566 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1082264891174920} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: Feedback enabled + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 513 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 114454282082524566} + characterCount: 16 + spriteCount: 0 + spaceCount: 1 + wordCount: 2 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &114548669865996182 MonoBehaviour: m_ObjectHideFlags: 1 @@ -320,6 +399,6 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 0, y: 411.55017} - m_SizeDelta: {x: 263.2, y: 45} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 263.2, y: 60} m_Pivot: {x: 0.5, y: 0.5} diff --git a/Scripts/Modules/SceneObjectModule.cs b/Scripts/Modules/SceneObjectModule.cs index 6050d2f06..21f15b9bf 100644 --- a/Scripts/Modules/SceneObjectModule.cs +++ b/Scripts/Modules/SceneObjectModule.cs @@ -26,13 +26,14 @@ public void PlaceSceneObject(Transform obj, Vector3 targetScale) public void DeleteSceneObject(GameObject sceneObject) { this.RemoveFromSpatialHash(sceneObject); - ObjectUtils.Destroy(sceneObject); + ObjectUtils.Destroy(sceneObject, withUndo: true); } IEnumerator PlaceSceneObjectCoroutine(Transform obj, Vector3 targetScale) { + var go = obj.gameObject; // Don't let us direct select while placing - this.RemoveFromSpatialHash(obj.gameObject); + this.RemoveFromSpatialHash(go); var start = Time.realtimeSinceStartup; var currTime = 0f; @@ -83,9 +84,10 @@ IEnumerator PlaceSceneObjectCoroutine(Transform obj, Vector3 targetScale) yield return null; } obj.localScale = targetScale; - Selection.activeGameObject = obj.gameObject; + Selection.activeGameObject = go; - this.AddToSpatialHash(obj.gameObject); + this.AddToSpatialHash(go); + Undo.IncrementCurrentGroup(); } public void PlaceSceneObjects(Transform[] transforms, Vector3[] targetPositionOffsets, Quaternion[] targetRotations, Vector3[] targetScales) @@ -178,6 +180,7 @@ IEnumerator PlaceSceneObjectsCoroutine(Transform[] transforms, Vector3[] targetP } Selection.objects = objects; + Undo.IncrementCurrentGroup(); } } } diff --git a/Scripts/Modules/SerializedPreferencesModule.cs b/Scripts/Modules/SerializedPreferencesModule.cs index 08d341585..3d5754920 100644 --- a/Scripts/Modules/SerializedPreferencesModule.cs +++ b/Scripts/Modules/SerializedPreferencesModule.cs @@ -13,7 +13,7 @@ sealed class SerializedPreferencesModule : MonoBehaviour SerializedPreferences m_Preferences; [Serializable] - class SerializedPreferences : ISerializationCallbackReceiver + internal class SerializedPreferences : ISerializationCallbackReceiver { [SerializeField] SerializedPreferenceItem[] m_Items; @@ -41,10 +41,16 @@ public void OnAfterDeserialize() } } } + + public void Remove(Type type) + { + m_ItemDictionary.Remove(type); + m_Items = m_ItemDictionary.Values.ToArray(); + } } [Serializable] - class SerializedPreferenceItem + internal class SerializedPreferenceItem { [SerializeField] string m_Name; @@ -75,7 +81,7 @@ public string payload public void AddSerializer(ISerializePreferences serializer) { if (m_Preferences != null) - Deserialize(serializer); + Deserialize(m_Preferences, serializer); m_Serializers.Add(serializer); } @@ -87,18 +93,23 @@ public void RemoveSerializer(ISerializePreferences serializer) m_Serializers.Remove(serializer); } - internal void DeserializePreferences(string serializedPreferences) + internal void SetupWithPreferences(string serializedPreferences) + { + m_Preferences = DeserializePreferences(serializedPreferences, m_Serializers); + } + + internal static SerializedPreferences DeserializePreferences(string serializedPreferences, List serializers = null) { var preferences = JsonUtility.FromJson(serializedPreferences); - if (preferences != null) + if (preferences != null && serializers != null) { - m_Preferences = preferences; - - foreach (var serializer in m_Serializers) + foreach (var serializer in serializers) { - Deserialize(serializer); + Deserialize(preferences, serializer); } } + + return preferences; } internal string SerializePreferences() @@ -131,12 +142,16 @@ internal string SerializePreferences() return JsonUtility.ToJson(m_Preferences); } - void Deserialize(ISerializePreferences serializer) + static void Deserialize(SerializedPreferences preferences, ISerializePreferences serializer) { SerializedPreferenceItem item; - if (m_Preferences.items.TryGetValue(serializer.GetType(), out item)) + if (preferences.items.TryGetValue(serializer.GetType(), out item)) { - var payload = JsonUtility.FromJson(item.payload, Type.GetType(item.payloadType)); + var type = Type.GetType(item.payloadType); + if (type == null) + return; + + var payload = JsonUtility.FromJson(item.payload, type); serializer.OnDeserializePreferences(payload); } } diff --git a/Scripts/Modules/SnappingModule/HapticPulses.meta b/Scripts/Modules/SnappingModule/HapticPulses.meta new file mode 100644 index 000000000..78e653d52 --- /dev/null +++ b/Scripts/Modules/SnappingModule/HapticPulses.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 76dab90d1b2fe7e4cb9b649aff286821 +folderAsset: yes +timeCreated: 1510942918 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Modules/SnappingModule/HapticPulses/SubMenuButtonClick.asset b/Scripts/Modules/SnappingModule/HapticPulses/SubMenuButtonClick.asset new file mode 100644 index 000000000..d1e0d5940 --- /dev/null +++ b/Scripts/Modules/SnappingModule/HapticPulses/SubMenuButtonClick.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1efd705dfe960584581b3390e04777f1, type: 3} + m_Name: SubMenuButtonClick + m_EditorClassIdentifier: + m_Duration: 0.05 + m_Intensity: 0.35 + m_FadeIn: 0 + m_FadeOut: 0 diff --git a/Scripts/Modules/SnappingModule/HapticPulses/SubMenuButtonClick.asset.meta b/Scripts/Modules/SnappingModule/HapticPulses/SubMenuButtonClick.asset.meta new file mode 100644 index 000000000..741251808 --- /dev/null +++ b/Scripts/Modules/SnappingModule/HapticPulses/SubMenuButtonClick.asset.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ad8089d07bd48a047b9d6b45f7a4fd57 +timeCreated: 1510943030 +licenseType: Pro +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Modules/SnappingModule/Prefabs/MenuFaceSnapping.prefab b/Scripts/Modules/SnappingModule/Prefabs/MenuFaceSnapping.prefab index 62c4633a7..d99f2924b 100644 --- a/Scripts/Modules/SnappingModule/Prefabs/MenuFaceSnapping.prefab +++ b/Scripts/Modules/SnappingModule/Prefabs/MenuFaceSnapping.prefab @@ -107,6 +107,7 @@ GameObject: - component: {fileID: 224000011296668950} - component: {fileID: 114000010948304686} - component: {fileID: 222000010942830010} + - component: {fileID: 114863593104786612} m_Layer: 5 m_Name: Manipulator m_TagString: Untagged @@ -210,6 +211,7 @@ GameObject: m_Component: - component: {fileID: 224000011333867530} - component: {fileID: 114000013071561082} + - component: {fileID: 114397974832724302} m_Layer: 5 m_Name: Pivot m_TagString: Untagged @@ -280,6 +282,7 @@ GameObject: - component: {fileID: 114000011539206294} - component: {fileID: 114000013313040984} - component: {fileID: 114056734150045564} + - component: {fileID: 114270311254005908} m_Layer: 5 m_Name: BackButton m_TagString: Untagged @@ -335,6 +338,7 @@ GameObject: - component: {fileID: 224000011344157490} - component: {fileID: 114000010532990664} - component: {fileID: 222000012330798060} + - component: {fileID: 114598190590722842} m_Layer: 5 m_Name: RotateObject m_TagString: Untagged @@ -403,6 +407,7 @@ GameObject: - component: {fileID: 224000012376581548} - component: {fileID: 114000012781285154} - component: {fileID: 222000013846753968} + - component: {fileID: 114433705572082042} m_Layer: 5 m_Name: LimitRadius m_TagString: Untagged @@ -539,6 +544,7 @@ GameObject: - component: {fileID: 224000011269624134} - component: {fileID: 114000011740143044} - component: {fileID: 222000010014886574} + - component: {fileID: 114585731372708882} m_Layer: 5 m_Name: GroundSnapping m_TagString: Untagged @@ -572,6 +578,7 @@ GameObject: - component: {fileID: 224000011535763916} - component: {fileID: 114000012943056720} - component: {fileID: 222000012933658470} + - component: {fileID: 114818556804415882} m_Layer: 5 m_Name: SurfaceSnapping m_TagString: Untagged @@ -590,6 +597,7 @@ GameObject: - component: {fileID: 114000013726484858} - component: {fileID: 222000012289411126} - component: {fileID: 114000012299972308} + - component: {fileID: 114304160726869102} m_Layer: 5 m_Name: EnableSnapping m_TagString: Untagged @@ -640,6 +648,7 @@ GameObject: m_Component: - component: {fileID: 224000013887046414} - component: {fileID: 114000011689962350} + - component: {fileID: 114670244529062318} m_Layer: 5 m_Name: Bounds m_TagString: Untagged @@ -742,6 +751,7 @@ GameObject: - component: {fileID: 224000013602175086} - component: {fileID: 114000013490178622} - component: {fileID: 222000012650615686} + - component: {fileID: 114595155424188078} m_Layer: 5 m_Name: Direct m_TagString: Untagged @@ -1313,7 +1323,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 9cd7d931d5a6d944f94aedf08db2dea1, type: 3} m_Name: m_EditorClassIdentifier: - m_BackButton: {fileID: 114000013313040984} + m_BackButton: {fileID: 114270311254005908} + m_ButtonClickPulse: {fileID: 11400000, guid: f66cb0a158f54124aa4158bbad3ed702, type: 2} + m_ButtonHoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} --- !u!114 &114000011689962350 MonoBehaviour: m_ObjectHideFlags: 1 @@ -2341,6 +2353,54 @@ MonoBehaviour: - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &114270311254005908 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011386972348} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d6fdf9e0896ac3f4e94809a2cb14ceb8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: f66cb0a158f54124aa4158bbad3ed702, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114854863929144100} + m_Button: {fileID: 114000013313040984} +--- !u!114 &114304160726869102 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013416106312} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114422380110548290} + m_Toggle: {fileID: 114000013726484858} +--- !u!114 &114397974832724302 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011017939822} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114768966837101286} + m_Toggle: {fileID: 114000013071561082} --- !u!114 &114422380110548290 MonoBehaviour: m_ObjectHideFlags: 1 @@ -2453,6 +2513,22 @@ MonoBehaviour: - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &114433705572082042 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012316381912} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114837802559842038} + m_Toggle: {fileID: 114000012781285154} --- !u!114 &114487886979728018 MonoBehaviour: m_ObjectHideFlags: 1 @@ -2677,6 +2753,70 @@ MonoBehaviour: - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &114585731372708882 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013321801100} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114833023654325632} + m_Toggle: {fileID: 114000011740143044} +--- !u!114 &114595155424188078 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013718046988} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114758890587099868} + m_Toggle: {fileID: 114000013490178622} +--- !u!114 &114598190590722842 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012102579994} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114936804563099460} + m_Toggle: {fileID: 114000010532990664} +--- !u!114 &114670244529062318 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013493931504} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114487886979728018} + m_Toggle: {fileID: 114000011689962350} --- !u!114 &114758890587099868 MonoBehaviour: m_ObjectHideFlags: 1 @@ -2901,6 +3041,22 @@ MonoBehaviour: - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &114818556804415882 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013390902142} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114243426776915280} + m_Toggle: {fileID: 114000012943056720} --- !u!114 &114833023654325632 MonoBehaviour: m_ObjectHideFlags: 1 @@ -3237,6 +3393,22 @@ MonoBehaviour: - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &114863593104786612 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000010462312398} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114547171262664456} + m_Toggle: {fileID: 114000010948304686} --- !u!114 &114936804563099460 MonoBehaviour: m_ObjectHideFlags: 1 @@ -4381,7 +4553,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: -0.0000076293945, y: 0.000015258789} + m_AnchoredPosition: {x: -0.0000076293945, y: 0.000030517578} m_SizeDelta: {x: 279.79852, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!224 &224000013713290898 diff --git a/Scripts/Modules/SnappingModule/SnappingModule.cs b/Scripts/Modules/SnappingModule/SnappingModule.cs index 6c00c074b..ef05bd6d1 100644 --- a/Scripts/Modules/SnappingModule/SnappingModule.cs +++ b/Scripts/Modules/SnappingModule/SnappingModule.cs @@ -952,10 +952,12 @@ void SetDependentTogglesGhosted() toggle.graphic.gameObject.SetActive(!m_Preferences.disableAll); } - foreach (var text in m_SnappingModuleSettingsUI.GetComponentsInChildren(true)) +#if INCLUDE_TEXT_MESH_PRO + foreach (var text in m_SnappingModuleSettingsUI.GetComponentsInChildren(true)) { text.color = m_Preferences.disableAll ? Color.gray : Color.white; } +#endif } void SetSessionGradientMaterial(GradientPair gradientPair) diff --git a/Scripts/Modules/TooltipModule/TooltipUI.cs b/Scripts/Modules/TooltipModule/TooltipUI.cs index e797859d2..fc5d7cfee 100644 --- a/Scripts/Modules/TooltipModule/TooltipUI.cs +++ b/Scripts/Modules/TooltipModule/TooltipUI.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR +#if UNITY_EDITOR using System; using UnityEditor.Experimental.EditorVR; using UnityEngine; diff --git a/Scripts/Modules/WorkspaceModule.cs b/Scripts/Modules/WorkspaceModule.cs index b27d46c78..41f55ed53 100644 --- a/Scripts/Modules/WorkspaceModule.cs +++ b/Scripts/Modules/WorkspaceModule.cs @@ -167,6 +167,9 @@ public void OnDeserializePreferences(object obj) internal void CreateWorkspace(Type t, Action createdCallback = null) { + if (!typeof(IWorkspace).IsAssignableFrom(t)) + return; + // HACK: MiniWorldWorkspace is not working in single pass yet if (t == typeof(MiniWorldWorkspace) && PlayerSettings.stereoRenderingPath != StereoRenderingPath.MultiPass) { diff --git a/Scripts/Proxies/Data/SerializedProxyFeedback.cs b/Scripts/Proxies/Data/SerializedProxyFeedback.cs new file mode 100644 index 000000000..a00dc1ad7 --- /dev/null +++ b/Scripts/Proxies/Data/SerializedProxyFeedback.cs @@ -0,0 +1,124 @@ +#if UNITY_EDITOR +using System; +using UnityEngine; +using UnityEngine.InputNew; + +namespace UnityEditor.Experimental.EditorVR.Proxies +{ + [Serializable] + class SerializedProxyFeedback + { + public SerializedProxyNodeFeedback leftNode; + public SerializedProxyNodeFeedback rightNode; + } + + /// + /// Used as globally unique identifiers for feedback requests + /// They are used to relate feedback requests to the persistent count of visible presentations used to suppress feedback + /// + [Serializable] + class RequestKey + { + /// + /// The control index used to identify the related affordance + /// + [SerializeField] + VRInputDevice.VRControl m_Control; + + /// + /// The tooltip text that was presented + /// + [SerializeField] + string m_TooltipText; + + public void UpdateValues(ProxyFeedbackRequest request) + { + m_Control = request.control; + m_TooltipText = request.tooltipText; + } + + public bool HasTooltip() + { + return !string.IsNullOrEmpty(m_TooltipText); + } + + public override int GetHashCode() + { + var hashCode = (int)m_Control; + + if (m_TooltipText != null) + hashCode ^= m_TooltipText.GetHashCode(); + + return hashCode; + } + + public override bool Equals(object obj) + { + if (obj == null) + return false; + + if (!(obj is RequestKey)) + return false; + + var key = (RequestKey)obj; + return m_Control == key.m_Control && string.Equals(m_TooltipText, key.m_TooltipText); + } + + public override string ToString() + { + return string.Format("{0}: {1}", m_Control, m_TooltipText); + } + } + + /// + /// Contains per-request persistent data + /// + [Serializable] + class RequestData + { + [SerializeField] + int m_Presentations; + + readonly Action m_OnBecameVisible; + + /// + /// How many times the user viewed the presentation of this type of request + /// + public int presentations + { + get { return m_Presentations; } + set { m_Presentations = value; } + } + + public bool visibleThisPresentation { get; set; } + + public Action onBecameVisible + { + get { return m_OnBecameVisible; } + } + + public RequestData() + { + m_OnBecameVisible = OnBecameVisible; + } + + void OnBecameVisible() + { + if (!visibleThisPresentation) + presentations++; + + visibleThisPresentation = true; + } + } + + /// + /// Used to store persistent data about feedback requests + /// + [Serializable] + class SerializedProxyNodeFeedback + { + public RequestKey[] keys; + public RequestData[] values; + } +} +#endif diff --git a/Scripts/Proxies/Data/SerializedProxyFeedback.cs.meta b/Scripts/Proxies/Data/SerializedProxyFeedback.cs.meta new file mode 100644 index 000000000..77bb88bc5 --- /dev/null +++ b/Scripts/Proxies/Data/SerializedProxyFeedback.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: fc2269803667794408d38030eaccab4c +timeCreated: 1512512089 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Proxies/ProxyNode.cs b/Scripts/Proxies/ProxyNode.cs index 8a41add78..ae154ee99 100644 --- a/Scripts/Proxies/ProxyNode.cs +++ b/Scripts/Proxies/ProxyNode.cs @@ -317,102 +317,6 @@ public void OnDestroy() } } - /// - /// Used as globally unique identifiers for feedback requests - /// They are used to relate feedback requests to the persistent count of visible presentations used to suppress feedback - /// - [Serializable] - internal class RequestKey - { - /// - /// The control index used to identify the related affordance - /// - [SerializeField] - VRControl m_Control; - - /// - /// The tooltip text that was presented - /// - [SerializeField] - string m_TooltipText; - - public void UpdateValues(ProxyFeedbackRequest request) - { - m_Control = request.control; - m_TooltipText = request.tooltipText; - } - - public override int GetHashCode() - { - var hashCode = (int)m_Control; - - if (m_TooltipText != null) - hashCode ^= m_TooltipText.GetHashCode(); - - return hashCode; - } - - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (!(obj is RequestKey)) - return false; - - var key = (RequestKey)obj; - return m_Control == key.m_Control && string.Equals(m_TooltipText, key.m_TooltipText); - } - } - - /// - /// Contains per-request persistent data - /// - [Serializable] - internal class RequestData - { - readonly Action m_OnBecameVisible; - - [SerializeField] - int m_Presentations; - - /// - /// How many times the user viewed the presentation of this type of request - /// - public int presentations - { - get { return m_Presentations; } - set { m_Presentations = value; } - } - - public bool visibleThisPresentation { get; set; } - - public Action onBecameVisible { get { return m_OnBecameVisible; } } - - public RequestData() - { - m_OnBecameVisible = OnBecameVisible; - } - - void OnBecameVisible() - { - if (!visibleThisPresentation) - presentations++; - - visibleThisPresentation = true; - } - } - - /// - /// Used to store persistent data about feedback requests - /// - [Serializable] - internal class SerializedFeedback - { - public RequestKey[] keys; - public RequestData[] values; - } - const string k_ZWritePropertyName = "_ZWrite"; const float k_LastFacingAngleWeight = 0.1f; // How much extra emphasis to give the last facing angle to prevent 'jitter' when looking at a controller on a boundary @@ -461,7 +365,7 @@ internal class SerializedFeedback FacingDirection m_FacingDirection = FacingDirection.Back; - SerializedFeedback m_SerializedFeedback; + SerializedProxyNodeFeedback m_SerializedFeedback; readonly List m_FeedbackRequests = new List(); readonly Dictionary m_RequestData = new Dictionary(); @@ -848,25 +752,29 @@ public void ClearFeedbackRequests(IRequestFeedback caller) } } - public SerializedFeedback OnSerializePreferences() + public SerializedProxyNodeFeedback OnSerializePreferences() { - if (m_SerializedFeedback != null) + if (m_RequestData.Count == 0) + return m_SerializedFeedback; + + if (m_SerializedFeedback == null) + m_SerializedFeedback = new SerializedProxyNodeFeedback(); + + var keys = new List(); + var values = new List(); + foreach (var kvp in m_RequestData) { - var count = m_RequestData.Count; - var keys = new RequestKey[count]; - var values = new RequestData[count]; - count = 0; - foreach (var kvp in m_RequestData) - { - keys[count] = kvp.Key; - values[count] = kvp.Value; - count++; - } + var requestKey = kvp.Key; + if (!requestKey.HasTooltip()) + continue; - m_SerializedFeedback.keys = keys; - m_SerializedFeedback.values = values; + keys.Add(requestKey); + values.Add(kvp.Value); } + m_SerializedFeedback.keys = keys.ToArray(); + m_SerializedFeedback.values = values.ToArray(); + return m_SerializedFeedback; } @@ -875,7 +783,7 @@ public void OnDeserializePreferences(object obj) if (obj == null) return; - m_SerializedFeedback = (SerializedFeedback)obj; + m_SerializedFeedback = (SerializedProxyNodeFeedback)obj; if (m_SerializedFeedback.keys == null) return; diff --git a/Scripts/Proxies/TwoHandedProxyBase.cs b/Scripts/Proxies/TwoHandedProxyBase.cs index ec0bdbca6..4b3f7b35f 100644 --- a/Scripts/Proxies/TwoHandedProxyBase.cs +++ b/Scripts/Proxies/TwoHandedProxyBase.cs @@ -27,13 +27,6 @@ public enum FacingDirection abstract class TwoHandedProxyBase : MonoBehaviour, IProxy, IFeedbackReceiver, ISetTooltipVisibility, ISetHighlight, ISerializePreferences { - [Serializable] - class SerializedFeedback - { - public ProxyNode.SerializedFeedback leftNode; - public ProxyNode.SerializedFeedback rightNode; - } - [SerializeField] protected GameObject m_LeftHandProxyPrefab; @@ -214,16 +207,22 @@ public object OnSerializePreferences() if (!active) return null; - return new SerializedFeedback + var leftNode = m_LeftProxyNode.OnSerializePreferences(); + var rightNode = m_RightProxyNode.OnSerializePreferences(); + + if (leftNode == null && rightNode == null) + return null; + + return new SerializedProxyFeedback { - leftNode = m_LeftProxyNode.OnSerializePreferences(), - rightNode = m_RightProxyNode.OnSerializePreferences() + leftNode = leftNode, + rightNode = rightNode }; } public void OnDeserializePreferences(object obj) { - var serializedFeedback = (SerializedFeedback)obj; + var serializedFeedback = (SerializedProxyFeedback)obj; m_LeftProxyNode.OnDeserializePreferences(serializedFeedback.leftNode); m_RightProxyNode.OnDeserializePreferences(serializedFeedback.rightNode); diff --git a/Scripts/UI/SubmenuFace.cs b/Scripts/UI/SubmenuFace.cs index fa7fbae1f..9c29d26eb 100644 --- a/Scripts/UI/SubmenuFace.cs +++ b/Scripts/UI/SubmenuFace.cs @@ -1,22 +1,40 @@ #if UNITY_EDITOR +using System; +using UnityEditor.Experimental.EditorVR.Core; using UnityEditor.Experimental.EditorVR.Helpers; using UnityEngine; using UnityEngine.Events; -using UnityEngine.UI; namespace UnityEditor.Experimental.EditorVR.Menus { - class SubmenuFace : MonoBehaviour + class SubmenuFace : MonoBehaviour, IControlHaptics, IRayToNode { [SerializeField] - Button m_BackButton; + MainMenuButton m_BackButton; + + [SerializeField] + HapticPulse m_ButtonClickPulse; + + [SerializeField] + HapticPulse m_ButtonHoverPulse; public GradientPair gradientPair { get; set; } - public void SetupBackButton(UnityAction backAction) + public void SetupBackButton(Action backAction) + { + m_BackButton.hovered += OnButtonHovered; + m_BackButton.clicked += OnButtonClicked; + m_BackButton.clicked += backAction; + } + + void OnButtonClicked(Transform rayOrigin) + { + this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_ButtonClickPulse); + } + + void OnButtonHovered(Transform rayOrigin, Type buttonType, string buttonDescription) { - m_BackButton.onClick.RemoveAllListeners(); - m_BackButton.onClick.AddListener(backAction); + this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_ButtonHoverPulse); } } } diff --git a/Scripts/Utilities/ObjectUtils.cs b/Scripts/Utilities/ObjectUtils.cs index e22160361..1c499cbff 100644 --- a/Scripts/Utilities/ObjectUtils.cs +++ b/Scripts/Utilities/ObjectUtils.cs @@ -149,7 +149,9 @@ public static Bounds GetBounds(Transform transform) b.center = k_Transforms[0].position; foreach (var t in k_Transforms) + { b.Encapsulate(t.position); + } } return b; @@ -202,6 +204,15 @@ public static Component AddComponent(Type type, GameObject go) return component; } + public static T CopyComponent(T sourceComponent, GameObject targetGameObject) where T : Component + { + var sourceType = sourceComponent.GetType(); + var clonedTargetComponent = AddComponent(sourceType, targetGameObject); + EditorUtility.CopySerialized(sourceComponent, clonedTargetComponent); + + return (T)clonedTargetComponent; + } + static IEnumerable GetAssignableTypes(Type type, Func predicate = null) { var list = new List(); @@ -256,7 +267,7 @@ public static IEnumerable GetExtensionsOfClass(Type type) return Enumerable.Empty(); } - public static void Destroy(UnityObject o, float t = 0f) + public static void Destroy(UnityObject o, float t = 0f, bool withUndo = false) { if (Application.isPlaying) { @@ -266,20 +277,30 @@ public static void Destroy(UnityObject o, float t = 0f) else { if (Mathf.Approximately(t, 0f)) - UnityObject.DestroyImmediate(o); + { + if (withUndo) + Undo.DestroyObjectImmediate(o); + else + UnityObject.DestroyImmediate(o); + } else + { VRView.StartCoroutine(DestroyInSeconds(o, t)); + } } #endif } - static IEnumerator DestroyInSeconds(UnityObject o, float t) + static IEnumerator DestroyInSeconds(UnityObject o, float t, bool withUndo = false) { var startTime = Time.realtimeSinceStartup; while (Time.realtimeSinceStartup <= startTime + t) yield return null; - UnityObject.DestroyImmediate(o); + if (withUndo) + Undo.DestroyObjectImmediate(o); + else + UnityObject.DestroyImmediate(o); } /// diff --git a/Tests/Editor/Unit/Core/EditingContextManagerTests.cs b/Tests/Editor/Unit/Core/EditingContextManagerTests.cs index b37d42d43..c79876178 100644 --- a/Tests/Editor/Unit/Core/EditingContextManagerTests.cs +++ b/Tests/Editor/Unit/Core/EditingContextManagerTests.cs @@ -1,172 +1,169 @@ -#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER -using System; -using System.IO; -using UnityEngine; -using UnityEditor; -using System.Collections.Generic; -using NUnit.Framework; -using UnityEditor.Experimental.EditorVR.Core; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEditor.Experimental.EditorVR.Tools; - -namespace UnityEditor.Experimental.EditorVR.Tests.Core -{ - [TestFixture] - public class EditingContextManagerTests - { - GameObject go; - EditorVRContext context, context2; - EditingContextManager manager; - EditingContextManagerSettings settings, newSettings; - SetEditingContextImplementor contextSetter; - - [OneTimeSetUp] - public void Setup() - { - manager = EditingContextManager.s_Instance; - go = new GameObject("context test object"); - var transformTool = go.AddComponent(); - var createPrimitiveTool = go.AddComponent(); - - context = ScriptableObject.CreateInstance(); - context.name = "Some Other Context"; - context.m_DefaultToolStack = new List(); - context.m_DefaultToolStack.Add(MonoScript.FromMonoBehaviour(transformTool)); - context.m_DefaultToolStack.Add(MonoScript.FromMonoBehaviour(createPrimitiveTool)); - - context2 = ScriptableObject.CreateInstance(); - context2.name = "Yet Another Context"; - context2.m_DefaultToolStack = context.m_DefaultToolStack; - - settings = ScriptableObject.CreateInstance(); - settings.defaultContextName = "Custom Default Context"; - newSettings = ScriptableObject.CreateInstance(); - newSettings.defaultContextName = "New Custom Default Context"; - } - - [Test] - public void Initializes_WithDefaultContext() - { - Assert.AreEqual(manager.defaultContext, manager.currentContext); - } - - [Test] - public void Initializes_ISetEditingContextMethods() - { - Assert.IsNotNull(ISetEditingContextMethods.getAvailableEditingContexts); - Assert.IsNotNull(ISetEditingContextMethods.getPreviousEditingContexts); - Assert.IsNotNull(ISetEditingContextMethods.setEditingContext); - Assert.IsNotNull(ISetEditingContextMethods.restorePreviousEditingContext); - } - - [Test] - public void SetEditingContext_DoesNothing_IfNull() - { - var beginningContext = manager.currentContext; - manager.SetEditingContext(null); - Assert.AreEqual(beginningContext, manager.currentContext); - } - - [Test] - public void SetEditingContext_SetsCurrentContext_IfNotNull() - { - manager.SetEditingContext(context); - Assert.AreEqual(context, manager.currentContext); - } - - [Test] - public void RestorePreviousContext_SetsPreviousContextToCurrent() - { - var beginningContext = manager.currentContext; - manager.SetEditingContext(context2); - Assert.AreNotEqual(beginningContext, manager.currentContext); - - manager.RestorePreviousContext(); - Assert.AreEqual(beginningContext, manager.currentContext); - } - - [Test] - public void LoadProjectSettings_IfAssetFound() - { - EditingContextManager.SaveProjectSettings(settings); - var loaded = EditingContextManager.LoadProjectSettings(); - Assert.AreEqual(settings.defaultContextName, loaded.defaultContextName); - } - - [Test] - public void LoadProjectSettings_IfAssetNotFound() - { - if (File.Exists(EditingContextManager.k_SettingsPath)) - File.Delete(EditingContextManager.k_SettingsPath); - - var loaded = EditingContextManager.LoadProjectSettings(); - Assert.IsInstanceOf(loaded); - Assert.IsNull(loaded.defaultContextName); - } - - [Test] - public void LoadUserSettings_NewerThanProjectSettings() - { - EditingContextManager.SaveUserSettings(newSettings); - var loaded = EditingContextManager.LoadUserSettings(); - Assert.AreEqual(newSettings.defaultContextName, loaded.defaultContextName); - } - - [Test] - public void LoadUserSettings_OlderThanProjectSettings() - { - EditingContextManager.SaveUserSettings(newSettings); - EditingContextManager.SaveProjectSettings(settings); - - var loaded = EditingContextManager.LoadUserSettings(); - Assert.AreEqual(settings.defaultContextName, loaded.defaultContextName); - } - - [Test] - public void LoadUserSettings_ProjectSettingsFallback() - { - if (File.Exists(EditingContextManager.k_UserSettingsPath)) - File.Delete(EditingContextManager.k_UserSettingsPath); - - var projectSettings = EditingContextManager.LoadProjectSettings(); - var userSettings = EditingContextManager.LoadUserSettings(); - - Assert.AreEqual(projectSettings.defaultContextName, userSettings.defaultContextName); - } - - [Test] - public void SaveProjectSettings_UpdatesProjectSettingsFile() - { - var path = EditingContextManager.k_SettingsPath; - var lastModTime = File.GetLastWriteTime(path); - EditingContextManager.SaveProjectSettings(settings); - - Assert.AreEqual(JsonUtility.ToJson(settings, true), File.ReadAllText(path)); - Assert.Greater(File.GetLastWriteTime(path), lastModTime); - } - - [Test] - public void SaveUserSettings_UpdatesUserSettingsFile() - { - var path = EditingContextManager.k_UserSettingsPath; - var lastModTime = File.GetLastWriteTime(path); - EditingContextManager.SaveUserSettings(newSettings); - - Assert.AreEqual(JsonUtility.ToJson(newSettings, true), File.ReadAllText(path)); - Assert.Greater(File.GetLastWriteTime(path), lastModTime); - } - - [OneTimeTearDown] - public void Cleanup() - { - ObjectUtils.Destroy(go); - manager.SetEditingContext(manager.defaultContext); - ObjectUtils.Destroy(context); - ObjectUtils.Destroy(context2); - } - } - - class SetEditingContextImplementor : ISetEditingContext { } -} - -#endif \ No newline at end of file +#if UNITY_EDITOR && UNITY_2017_2_OR_NEWER +using System.IO; +using UnityEngine; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEditor.Experimental.EditorVR.Core; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEditor.Experimental.EditorVR.Tools; + +namespace UnityEditor.Experimental.EditorVR.Tests.Core +{ + [TestFixture] + public class EditingContextManagerTests + { + GameObject go; + EditorVRContext context, context2; + EditingContextManager manager; + EditingContextManagerSettings settings, newSettings; + SetEditingContextImplementor contextSetter; + + [OneTimeSetUp] + public void Setup() + { + manager = EditingContextManager.s_Instance; + go = new GameObject("context test object"); + var transformTool = go.AddComponent(); + var createPrimitiveTool = go.AddComponent(); + + context = ScriptableObject.CreateInstance(); + context.name = "Some Other Context"; + context.m_DefaultToolStack = new List(); + context.m_DefaultToolStack.Add(MonoScript.FromMonoBehaviour(transformTool)); + context.m_DefaultToolStack.Add(MonoScript.FromMonoBehaviour(createPrimitiveTool)); + + context2 = ScriptableObject.CreateInstance(); + context2.name = "Yet Another Context"; + context2.m_DefaultToolStack = context.m_DefaultToolStack; + + settings = ScriptableObject.CreateInstance(); + settings.defaultContextName = "Custom Default Context"; + newSettings = ScriptableObject.CreateInstance(); + newSettings.defaultContextName = "New Custom Default Context"; + } + + [Test] + public void Initializes_WithDefaultContext() + { + Assert.AreEqual(EditingContextManager.defaultContext, manager.currentContext); + } + + [Test] + public void Initializes_ISetEditingContextMethods() + { + Assert.IsNotNull(ISetEditingContextMethods.getAvailableEditingContexts); + Assert.IsNotNull(ISetEditingContextMethods.getPreviousEditingContexts); + Assert.IsNotNull(ISetEditingContextMethods.setEditingContext); + Assert.IsNotNull(ISetEditingContextMethods.restorePreviousEditingContext); + } + + [Test] + public void SetEditingContext_DoesNothing_IfNull() + { + var beginningContext = manager.currentContext; + manager.SetEditingContext(null); + Assert.AreEqual(beginningContext, manager.currentContext); + } + + [Test] + public void SetEditingContext_SetsCurrentContext_IfNotNull() + { + manager.SetEditingContext(context); + Assert.AreEqual(context, manager.currentContext); + } + + [Test] + public void RestorePreviousContext_SetsPreviousContextToCurrent() + { + var beginningContext = manager.currentContext; + manager.SetEditingContext(context2); + Assert.AreNotEqual(beginningContext, manager.currentContext); + + manager.RestorePreviousContext(); + Assert.AreEqual(beginningContext, manager.currentContext); + } + + [Test] + public void LoadProjectSettings_IfAssetFound() + { + EditingContextManager.SaveProjectSettings(settings); + var loaded = EditingContextManager.LoadProjectSettings(); + Assert.AreEqual(settings.defaultContextName, loaded.defaultContextName); + } + + [Test] + public void LoadProjectSettings_IfAssetNotFound() + { + if (File.Exists(EditingContextManager.k_SettingsPath)) + File.Delete(EditingContextManager.k_SettingsPath); + + var loaded = EditingContextManager.LoadProjectSettings(); + Assert.IsInstanceOf(loaded); + Assert.IsNull(loaded.defaultContextName); + } + + [Test] + public void LoadUserSettings_NewerThanProjectSettings() + { + EditingContextManager.SaveUserSettings(newSettings); + var loaded = EditingContextManager.LoadUserSettings(); + Assert.AreEqual(newSettings.defaultContextName, loaded.defaultContextName); + } + + [Test] + public void LoadUserSettings_OlderThanProjectSettings() + { + EditingContextManager.SaveUserSettings(newSettings); + EditingContextManager.SaveProjectSettings(settings); + + var loaded = EditingContextManager.LoadUserSettings(); + Assert.AreEqual(settings.defaultContextName, loaded.defaultContextName); + } + + [Test] + public void LoadUserSettings_ProjectSettingsFallback() + { + if (File.Exists(EditingContextManager.k_UserSettingsPath)) + File.Delete(EditingContextManager.k_UserSettingsPath); + + var projectSettings = EditingContextManager.LoadProjectSettings(); + var userSettings = EditingContextManager.LoadUserSettings(); + + Assert.AreEqual(projectSettings.defaultContextName, userSettings.defaultContextName); + } + + [Test] + public void SaveProjectSettings_UpdatesProjectSettingsFile() + { + var path = EditingContextManager.k_SettingsPath; + var lastModTime = File.GetLastWriteTime(path); + EditingContextManager.SaveProjectSettings(settings); + + Assert.AreEqual(JsonUtility.ToJson(settings, true), File.ReadAllText(path)); + Assert.Greater(File.GetLastWriteTime(path), lastModTime); + } + + [Test] + public void SaveUserSettings_UpdatesUserSettingsFile() + { + var path = EditingContextManager.k_UserSettingsPath; + var lastModTime = File.GetLastWriteTime(path); + EditingContextManager.SaveUserSettings(newSettings); + + Assert.AreEqual(JsonUtility.ToJson(newSettings, true), File.ReadAllText(path)); + Assert.Greater(File.GetLastWriteTime(path), lastModTime); + } + + [OneTimeTearDown] + public void Cleanup() + { + ObjectUtils.Destroy(go); + manager.SetEditingContext(EditingContextManager.defaultContext); + ObjectUtils.Destroy(context); + ObjectUtils.Destroy(context2); + } + } + + class SetEditingContextImplementor : ISetEditingContext { } +} +#endif diff --git a/Tools/AnnotationTool/AnnotationTool.cs b/Tools/AnnotationTool/AnnotationTool.cs index e25297e7e..b6b63dd52 100644 --- a/Tools/AnnotationTool/AnnotationTool.cs +++ b/Tools/AnnotationTool/AnnotationTool.cs @@ -5,6 +5,7 @@ using System.Linq; using UnityEditor.Experimental.EditorVR.Core; using UnityEditor.Experimental.EditorVR.Extensions; +using UnityEditor.Experimental.EditorVR.Menus; using UnityEditor.Experimental.EditorVR.Proxies; using UnityEditor.Experimental.EditorVR.UI; using UnityEditor.Experimental.EditorVR.Utilities; @@ -18,7 +19,7 @@ namespace UnityEditor.Experimental.EditorVR.Tools public class AnnotationTool : MonoBehaviour, ITool, ICustomActionMap, IUsesRayOrigin, IRayVisibilitySettings, IUsesRayOrigins, IInstantiateUI, IUsesMenuOrigins, IUsesCustomMenuOrigins, IUsesViewerScale, IUsesSpatialHash, IIsHoveringOverUI, IMultiDeviceTool, IUsesDeviceType, ISettingsMenuItemProvider, ISerializePreferences, ILinkedObject, - IUsesNode, IRequestFeedback + IUsesNode, IRequestFeedback, IConnectInterfaces { [Serializable] class Preferences @@ -107,7 +108,6 @@ public float brushSize Vector3 m_OriginalAnnotationPointerLocalScale; Coroutine m_AnnotationPointerVisibilityCoroutine; bool m_WasOverUI; - bool m_WasDoingUndoRedo; GameObject m_ColorPickerActivator; @@ -192,7 +192,10 @@ void OnDestroy() ObjectUtils.Destroy(m_ColorPicker.gameObject); if (m_BrushSizeUI) + { + this.DisconnectInterfaces(m_BrushSizeUI, rayOrigin); ObjectUtils.Destroy(m_BrushSizeUI.gameObject); + } if (m_ColorPickerActivator) ObjectUtils.Destroy(m_ColorPickerActivator); @@ -256,9 +259,6 @@ void Start() activator.showColorPicker = ShowColorPicker; activator.hideColorPicker = HideColorPicker; - activator.undoButtonClick += Undo.PerformUndo; - activator.redoButtonClick += Undo.PerformRedo; - var controls = new BindingDictionary(); InputUtils.GetBindingDictionaryFromActionMap(m_ActionMap, controls); @@ -312,7 +312,7 @@ void SetupBrushUI() var brushSize = m_Preferences.brushSize; m_AnnotationPointer.Resize(brushSize); - var brushSizeUi = this.InstantiateUI(m_BrushSizePrefab); + var brushSizeUi = this.InstantiateUI(m_BrushSizePrefab, rayOrigin: rayOrigin); m_BrushSizeUI = brushSizeUi.GetComponent(); var transform = brushSizeUi.transform; @@ -394,7 +394,8 @@ void SetupAnnotation() m_Widths.Clear(); m_Length = 0; - var go = new GameObject(string.Format(k_AnnotationFormatStrig,+ m_AnnotationHolder.childCount)); + var go = new GameObject(string.Format(k_AnnotationFormatStrig, m_AnnotationHolder.childCount)); + Undo.RegisterCreatedObjectUndo(go, "Annotation"); var goTrans = go.transform; goTrans.SetParent(m_AnnotationHolder); @@ -604,7 +605,6 @@ void FinalizeMesh() this.AddToSpatialHash(go); Undo.IncrementCurrentGroup(); - Undo.RegisterCreatedObjectUndo(go, "Create Annotation"); if (AnnotationFinished != null) { @@ -722,39 +722,6 @@ public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeCon consumeControl(draw); } } - else - { - // Secondary hand uses brush size input to do undo/redo - var value = annotationInput.changeBrushSize.value; - if (this.GetDeviceType() == DeviceType.Vive) - { - if (annotationInput.stickButton.wasJustPressed) - { - if (value > 0) - Undo.PerformRedo(); - else - Undo.PerformUndo(); - } - } - else - { - var doUndoRedo = Math.Abs(value) > 0.5f; - if (doUndoRedo != m_WasDoingUndoRedo) - { - m_WasDoingUndoRedo = doUndoRedo; - if (doUndoRedo) - { - if (value > 0) - Undo.PerformRedo(); - else - Undo.PerformUndo(); - } - } - - consumeControl(annotationInput.changeBrushSize); - consumeControl(annotationInput.vertical); - } - } if (isHeld) return; diff --git a/Tools/AnnotationTool/Prefabs/AnnotationUI.prefab b/Tools/AnnotationTool/Prefabs/AnnotationUI.prefab index 0ea924413..d09b90573 100644 --- a/Tools/AnnotationTool/Prefabs/AnnotationUI.prefab +++ b/Tools/AnnotationTool/Prefabs/AnnotationUI.prefab @@ -241,40 +241,6 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!1 &1036881825388254 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224393326463988594} - - component: {fileID: 222928571895566388} - - component: {fileID: 114395512104104094} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!1 &1099690223586730 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4940108482629240} - - component: {fileID: 33257561653289390} - - component: {fileID: 23652728190552066} - m_Layer: 0 - m_Name: ButtonMesh - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 --- !u!1 &1136647751248060 GameObject: m_ObjectHideFlags: 1 @@ -292,88 +258,6 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!1 &1141551173516660 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224963898299502848} - - component: {fileID: 222582790420601646} - - component: {fileID: 114007618893444894} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!1 &1167948277449984 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224333717671022096} - - component: {fileID: 33699724321051718} - - component: {fileID: 23309274037775718} - - component: {fileID: 114168715074745758} - - component: {fileID: 65270067782407046} - m_Layer: 5 - m_Name: Base - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1187994386522324 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4066649049098668} - m_Layer: 5 - m_Name: TooltipSource - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1279537530764624 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4230552379396688} - - component: {fileID: 114543901646842364} - m_Layer: 5 - m_Name: Undo - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1329748470766914 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4670339961100958} - m_Layer: 5 - m_Name: RotationPivot - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 --- !u!1 &1346101208067254 GameObject: m_ObjectHideFlags: 0 @@ -391,216 +275,6 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!1 &1347799845701476 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4702350181192430} - m_Layer: 5 - m_Name: TooltipSource - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1361017080451862 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4572708185800628} - - component: {fileID: 33824803535794784} - - component: {fileID: 23437852442812966} - m_Layer: 0 - m_Name: ButtonMesh - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1365241548943880 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224107373598291132} - - component: {fileID: 33095966663817246} - - component: {fileID: 23375274514904506} - - component: {fileID: 114257755424135964} - - component: {fileID: 65378884854788314} - m_Layer: 5 - m_Name: Base - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1382527450794256 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4843657865520138} - - component: {fileID: 114824239518982862} - m_Layer: 5 - m_Name: Redo - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1411372913666494 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224860733548256162} - - component: {fileID: 225914373114193260} - - component: {fileID: 223499351256631318} - m_Layer: 5 - m_Name: ButtonContentContainer - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1430967031119936 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224638576672757326} - - component: {fileID: 222975643046639372} - - component: {fileID: 114967506099497140} - m_Layer: 5 - m_Name: Icon - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1482568457756204 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224939432255965946} - m_Layer: 5 - m_Name: IconContainer - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1490901763651664 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4796074920551568} - m_Layer: 5 - m_Name: RotationPivot - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1603094234734992 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224124519857189990} - - component: {fileID: 225328779711015670} - - component: {fileID: 223502477285382174} - m_Layer: 5 - m_Name: ButtonContentContainer - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1619517534170012 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224388597326433990} - - component: {fileID: 222227951865979474} - - component: {fileID: 114481225842932662} - m_Layer: 5 - m_Name: Icon - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1863793980498380 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4166573009768210} - m_Layer: 5 - m_Name: TooltipTarget - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1887300028592862 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 224878234700512394} - m_Layer: 5 - m_Name: IconContainer - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!1 &1913076707455610 -GameObject: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 5 - m_Component: - - component: {fileID: 4602986436310456} - m_Layer: 5 - m_Name: TooltipTarget - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 --- !u!4 &4000010343588658 Transform: m_ObjectHideFlags: 1 @@ -643,359 +317,77 @@ Transform: - {fileID: 4000010343588658} m_Father: {fileID: 4626871607531114} m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4000012841704540 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000010255295176} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 4626871607531114} - - {fileID: 4230552379396688} - - {fileID: 4843657865520138} - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4000013117727556 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000012208465784} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -0} - m_LocalScale: {x: 4, y: 1, z: 4} - m_Children: [] - m_Father: {fileID: 4626871607531114} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4066649049098668 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1187994386522324} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0.01267001, y: 0.00078000035, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 4230552379396688} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!4 &4166573009768210 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1863793980498380} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0.025, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 4843657865520138} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!4 &4230552379396688 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1279537530764624} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0.006864082, y: 0.0018081665, z: 0.00087684765} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 4602986436310456} - - {fileID: 4066649049098668} - - {fileID: 4670339961100958} - m_Father: {fileID: 4000012841704540} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4572708185800628 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1361017080451862} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: -0, z: 0.00009} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 224939432255965946} - m_Father: {fileID: 224860733548256162} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4602986436310456 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1913076707455610} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0.025, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 4230552379396688} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!4 &4626871607531114 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1346101208067254} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0.006864082, y: 0.0018081665, z: -0.032373153} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 4000013117727556} - - {fileID: 4000012336507532} - m_Father: {fileID: 4000012841704540} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4663617041298854 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1136647751248060} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0.0004, z: 0} - m_LocalScale: {x: 0.5, y: 0.25, z: 0.5} - m_Children: [] - m_Father: {fileID: 4000012336507532} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4670339961100958 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1329748470766914} - m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 224107373598291132} - - {fileID: 224124519857189990} - m_Father: {fileID: 4230552379396688} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0} ---- !u!4 &4702350181192430 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1347799845701476} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0.01267001, y: 0.00078000035, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 4843657865520138} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} ---- !u!4 &4796074920551568 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1490901763651664} - m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 224333717671022096} - - {fileID: 224860733548256162} - m_Father: {fileID: 4843657865520138} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0} ---- !u!4 &4843657865520138 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1382527450794256} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0.006864082, y: 0.0018081665, z: 0.029026847} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 4166573009768210} - - {fileID: 4702350181192430} - - {fileID: 4796074920551568} - m_Father: {fileID: 4000012841704540} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!4 &4940108482629240 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1099690223586730} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: -0, z: 0.00009} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 224878234700512394} - m_Father: {fileID: 224124519857189990} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!23 &23000011095290868 -MeshRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000011463743810} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_Materials: - - {fileID: 2100000, guid: ed6062fbd167bed46b70b3ae75c81624, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!23 &23309274037775718 -MeshRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1167948277449984} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_MotionVectors: 0 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 - m_Materials: - - {fileID: 2100000, guid: 6adae681ad457e140ac31a9ac83c3a11, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!23 &23375274514904506 -MeshRenderer: + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4000012841704540 +Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1365241548943880} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_MotionVectors: 0 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 - m_Materials: - - {fileID: 2100000, guid: 6adae681ad457e140ac31a9ac83c3a11, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!23 &23437852442812966 -MeshRenderer: + m_GameObject: {fileID: 1000010255295176} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 4626871607531114} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4000013117727556 +Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1361017080451862} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_MotionVectors: 0 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 - m_Materials: - - {fileID: 2100000, guid: 38860ca708e7b5641ace5d1ed4e7c0fc, type: 2} - - {fileID: 2100000, guid: 7c873c9977af7044aa1412eb381756f8, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!23 &23652728190552066 + m_GameObject: {fileID: 1000012208465784} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -0} + m_LocalScale: {x: 4, y: 1, z: 4} + m_Children: [] + m_Father: {fileID: 4626871607531114} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4626871607531114 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1346101208067254} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0.006864082, y: 0.0018081665, z: -0.032373153} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 4000013117727556} + - {fileID: 4000012336507532} + m_Father: {fileID: 4000012841704540} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &4663617041298854 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1136647751248060} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0.0004, z: 0} + m_LocalScale: {x: 0.5, y: 0.25, z: 0.5} + m_Children: [] + m_Father: {fileID: 4000012336507532} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &23000011095290868 MeshRenderer: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1099690223586730} + m_GameObject: {fileID: 1000011463743810} m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 + m_CastShadows: 1 + m_ReceiveShadows: 1 m_DynamicOccludee: 1 - m_MotionVectors: 0 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 m_Materials: - - {fileID: 2100000, guid: 38860ca708e7b5641ace5d1ed4e7c0fc, type: 2} - - {fileID: 2100000, guid: 7c873c9977af7044aa1412eb381756f8, type: 2} + - {fileID: 2100000, guid: ed6062fbd167bed46b70b3ae75c81624, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -1003,7 +395,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 - m_PreserveUVs: 0 + m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 m_StitchLightmapSeams: 0 @@ -1056,34 +448,6 @@ MeshFilter: m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1000011463743810} m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} ---- !u!33 &33095966663817246 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1365241548943880} - m_Mesh: {fileID: 4300050, guid: 4f7e1c38dff4db9449be30d253d1bd8f, type: 3} ---- !u!33 &33257561653289390 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1099690223586730} - m_Mesh: {fileID: 4300000, guid: 7f7c3987753e1bf41bee70661b3eff03, type: 3} ---- !u!33 &33699724321051718 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1167948277449984} - m_Mesh: {fileID: 4300050, guid: 4f7e1c38dff4db9449be30d253d1bd8f, type: 3} ---- !u!33 &33824803535794784 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1361017080451862} - m_Mesh: {fileID: 4300000, guid: 7f7c3987753e1bf41bee70661b3eff03, type: 3} --- !u!33 &33923684612379296 MeshFilter: m_ObjectHideFlags: 1 @@ -1103,30 +467,6 @@ BoxCollider: serializedVersion: 2 m_Size: {x: 945.4, y: 1268, z: 10} m_Center: {x: 0, y: 0, z: 0} ---- !u!65 &65270067782407046 -BoxCollider: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1167948277449984} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 0.1, y: 0.0028786354, z: 0.07} - m_Center: {x: 0, y: -0.00000005960467, z: 0.000000008381907} ---- !u!65 &65378884854788314 -BoxCollider: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1365241548943880} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 0.1, y: 0.0028786354, z: 0.07} - m_Center: {x: 0, y: -0.00000005960467, z: 0.000000008381907} --- !u!114 &114000010240686482 MonoBehaviour: m_ObjectHideFlags: 1 @@ -1362,428 +702,71 @@ MonoBehaviour: m_IntArgument: 0 m_FloatArgument: 0 m_StringArgument: - m_BoolArgument: 0 - m_CallState: 1 - m_TypeName: UnityEngine.UI.Slider+SliderEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &114000013248295880 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000011582997490} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -98529514, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!114 &114000013959281966 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000010117119988} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!114 &114007618893444894 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1141551173516660} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_text: A - m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: 21452896fabdc4e4ea06c09c6ac05c9e, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: 2800c3c40f001db459e655626fba97bf, type: 2} - m_fontSharedMaterials: [] - m_fontMaterial: {fileID: 0} - m_fontMaterials: [] - m_fontColor32: - serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} - m_enableVertexGradient: 0 - m_fontColorGradient: - topLeft: {r: 1, g: 1, b: 1, a: 1} - topRight: {r: 1, g: 1, b: 1, a: 1} - bottomLeft: {r: 1, g: 1, b: 1, a: 1} - bottomRight: {r: 1, g: 1, b: 1, a: 1} - m_fontColorGradientPreset: {fileID: 0} - m_spriteAsset: {fileID: 0} - m_tintAllSprites: 0 - m_overrideHtmlColors: 0 - m_faceColor: - serializedVersion: 2 - rgba: 4294967295 - m_outlineColor: - serializedVersion: 2 - rgba: 4278190080 - m_fontSize: 203.4 - m_fontSizeBase: 36 - m_fontWeight: 400 - m_enableAutoSizing: 1 - m_fontSizeMin: 0 - m_fontSizeMax: 250 - m_fontStyle: 0 - m_textAlignment: 514 - m_isAlignmentEnumConverted: 1 - m_characterSpacing: 0 - m_wordSpacing: 0 - m_lineSpacing: 1 - m_lineSpacingMax: 0 - m_paragraphSpacing: 0 - m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 - m_wordWrappingRatios: 0.4 - m_overflowMode: 3 - m_firstOverflowCharacterIndex: -1 - m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_enableKerning: 1 - m_enableExtraPadding: 0 - checkPaddingRequired: 0 - m_isRichText: 1 - m_parseCtrlCharacters: 1 - m_isOrthographic: 1 - m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 - m_horizontalMapping: 0 - m_verticalMapping: 0 - m_uvLineOffset: 0 - m_geometrySortingOrder: 0 - m_firstVisibleCharacter: 0 - m_useMaxVisibleDescender: 1 - m_pageToDisplay: 1 - m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 0} - characterCount: 1 - spriteCount: 0 - spaceCount: 0 - wordCount: 1 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 - m_havePropertiesChanged: 1 - m_isUsingLegacyAnimationComponent: 0 - m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} - m_isInputParsingRequired: 1 - m_inputSource: 0 - m_hasFontAssetChanged: 0 - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - m_baseMaterial: {fileID: 0} - m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!114 &114168715074745758 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1167948277449984} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: c14051f25ea615549aeb702ebe3005d8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_NormalGradientPair: - a: {r: 0.9607843, g: 0.972549, b: 0.9764706, a: 1} - b: {r: 0.9607843, g: 0.972549, b: 0.9764706, a: 1} - m_HighlightGradientPair: - a: {r: 0.19607843, g: 0.2, b: 0.2, a: 1} - b: {r: 0.19607843, g: 0.2, b: 0.2, a: 1} - m_ButtonMeshRenderer: {fileID: 23437852442812966} - m_IconContainer: {fileID: 224939432255965946} - m_ContentContainer: {fileID: 224860733548256162} - m_CanvasGroup: {fileID: 225914373114193260} - m_Text: {fileID: 114395512104104094} - m_Icon: {fileID: 114967506099497140} - m_AlternateIconSprite: {fileID: 0} - m_NormalContentColor: {r: 0.101960786, g: 0.101960786, b: 0.101960786, a: 1} - m_DisabledColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_HighlightItemColor: {r: 0.101960786, g: 0.101960786, b: 0.101960786, a: 1} - m_HighlightItems: - - {fileID: 114967506099497140} - - {fileID: 0} - m_Interactable: 0 - m_IconHighlightedLocalZOffset: -0.0015 - m_BeginHighlightDuration: 0.25 - m_EndHighlightDuration: 0.167 - m_DelayBeforeReveal: 0 - m_HighlightZScaleMultiplier: 2 - m_ContainerContentsAnimationSpeedMultiplier: 1 ---- !u!114 &114257755424135964 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1365241548943880} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: c14051f25ea615549aeb702ebe3005d8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_NormalGradientPair: - a: {r: 0.9607843, g: 0.972549, b: 0.9764706, a: 1} - b: {r: 0.9607843, g: 0.972549, b: 0.9764706, a: 1} - m_HighlightGradientPair: - a: {r: 0.19607843, g: 0.2, b: 0.2, a: 1} - b: {r: 0.19607843, g: 0.2, b: 0.2, a: 1} - m_ButtonMeshRenderer: {fileID: 23652728190552066} - m_IconContainer: {fileID: 224878234700512394} - m_ContentContainer: {fileID: 224124519857189990} - m_CanvasGroup: {fileID: 225328779711015670} - m_Text: {fileID: 114007618893444894} - m_Icon: {fileID: 114481225842932662} - m_AlternateIconSprite: {fileID: 0} - m_NormalContentColor: {r: 0.101960786, g: 0.101960786, b: 0.101960786, a: 1} - m_DisabledColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_HighlightItemColor: {r: 0.101960786, g: 0.101960786, b: 0.101960786, a: 1} - m_HighlightItems: - - {fileID: 114481225842932662} - - {fileID: 0} - m_Interactable: 0 - m_IconHighlightedLocalZOffset: -0.0015 - m_BeginHighlightDuration: 0.25 - m_EndHighlightDuration: 0.167 - m_DelayBeforeReveal: 0 - m_HighlightZScaleMultiplier: 2 - m_ContainerContentsAnimationSpeedMultiplier: 1 ---- !u!114 &114360875105238964 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1346101208067254} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 39742408926c5694d89876057a60578a, type: 3} - m_Name: - m_EditorClassIdentifier: - m_TargetScale: {fileID: 4000013117727556} - m_Icon: {fileID: 4000012336507532} - m_Undo: {fileID: 1279537530764624} - m_Redo: {fileID: 1382527450794256} - m_PickerOffset: 0.045 ---- !u!114 &114395512104104094 + m_BoolArgument: 0 + m_CallState: 1 + m_TypeName: UnityEngine.UI.Slider+SliderEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &114000013248295880 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1036881825388254} + m_GameObject: {fileID: 1000011582997490} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Script: {fileID: -98529514, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 + m_RaycastTarget: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_text: A - m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: 21452896fabdc4e4ea06c09c6ac05c9e, type: 2} - m_sharedMaterial: {fileID: 2100000, guid: 2800c3c40f001db459e655626fba97bf, type: 2} - m_fontSharedMaterials: [] - m_fontMaterial: {fileID: 0} - m_fontMaterials: [] - m_fontColor32: - serializedVersion: 2 - rgba: 4294967295 - m_fontColor: {r: 1, g: 1, b: 1, a: 1} - m_enableVertexGradient: 0 - m_fontColorGradient: - topLeft: {r: 1, g: 1, b: 1, a: 1} - topRight: {r: 1, g: 1, b: 1, a: 1} - bottomLeft: {r: 1, g: 1, b: 1, a: 1} - bottomRight: {r: 1, g: 1, b: 1, a: 1} - m_fontColorGradientPreset: {fileID: 0} - m_spriteAsset: {fileID: 0} - m_tintAllSprites: 0 - m_overrideHtmlColors: 0 - m_faceColor: - serializedVersion: 2 - rgba: 4294967295 - m_outlineColor: + m_Texture: {fileID: 0} + m_UVRect: serializedVersion: 2 - rgba: 4278190080 - m_fontSize: 203.4 - m_fontSizeBase: 36 - m_fontWeight: 400 - m_enableAutoSizing: 1 - m_fontSizeMin: 0 - m_fontSizeMax: 250 - m_fontStyle: 0 - m_textAlignment: 514 - m_isAlignmentEnumConverted: 1 - m_characterSpacing: 0 - m_wordSpacing: 0 - m_lineSpacing: 0 - m_lineSpacingMax: 0 - m_paragraphSpacing: 0 - m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 - m_wordWrappingRatios: 0.4 - m_overflowMode: 3 - m_firstOverflowCharacterIndex: -1 - m_linkedTextComponent: {fileID: 0} - m_isLinkedTextComponent: 0 - m_enableKerning: 1 - m_enableExtraPadding: 0 - checkPaddingRequired: 0 - m_isRichText: 1 - m_parseCtrlCharacters: 1 - m_isOrthographic: 1 - m_isCullingEnabled: 0 - m_ignoreRectMaskCulling: 0 - m_ignoreCulling: 1 - m_horizontalMapping: 0 - m_verticalMapping: 0 - m_uvLineOffset: 0 - m_geometrySortingOrder: 0 - m_firstVisibleCharacter: 0 - m_useMaxVisibleDescender: 1 - m_pageToDisplay: 1 - m_margin: {x: 0, y: 0, z: 0, w: 0} - m_textInfo: - textComponent: {fileID: 0} - characterCount: 1 - spriteCount: 0 - spaceCount: 0 - wordCount: 1 - linkCount: 0 - lineCount: 1 - pageCount: 1 - materialCount: 1 - m_havePropertiesChanged: 1 - m_isUsingLegacyAnimationComponent: 0 - m_isVolumetricText: 0 - m_spriteAnimator: {fileID: 0} - m_isInputParsingRequired: 1 - m_inputSource: 0 - m_hasFontAssetChanged: 0 - m_subTextObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - m_baseMaterial: {fileID: 0} - m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!114 &114481225842932662 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1619517534170012} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: f51c2d173513e574f91a3666d94906b2, type: 2} - m_Color: {r: 0.101960786, g: 0.101960786, b: 0.101960786, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 21300000, guid: f7acf93d805e2dd42b4f32bed5d45ce8, type: 3} - m_Type: 0 - m_PreserveAspect: 1 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 2 ---- !u!114 &114543901646842364 + x: 0 + y: 0 + width: 1 + height: 1 +--- !u!114 &114000013959281966 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1279537530764624} + m_GameObject: {fileID: 1000010117119988} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 121a9b94e41e9e444af3e8069a887154, type: 3} + m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} m_Name: m_EditorClassIdentifier: - m_TooltipText: Undo - m_TooltipTarget: {fileID: 4602986436310456} - m_TooltipSource: {fileID: 4066649049098668} - m_TooltipAlignment: 0 ---- !u!114 &114824239518982862 + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!114 &114360875105238964 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1382527450794256} + m_GameObject: {fileID: 1346101208067254} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 121a9b94e41e9e444af3e8069a887154, type: 3} + m_Script: {fileID: 11500000, guid: 39742408926c5694d89876057a60578a, type: 3} m_Name: m_EditorClassIdentifier: - m_TooltipText: Redo - m_TooltipTarget: {fileID: 4166573009768210} - m_TooltipSource: {fileID: 4702350181192430} - m_TooltipAlignment: 0 + m_TargetScale: {fileID: 4000013117727556} + m_Icon: {fileID: 4000012336507532} + m_PickerOffset: 0.045 --- !u!114 &114955240123553084 MonoBehaviour: m_ObjectHideFlags: 1 @@ -1796,33 +779,6 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_SelectionFlags: 3 ---- !u!114 &114967506099497140 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1430967031119936} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: f51c2d173513e574f91a3666d94906b2, type: 2} - m_Color: {r: 0.101960786, g: 0.101960786, b: 0.101960786, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 21300000, guid: 6c24010c054434e468a95292a7af0f67, type: 3} - m_Type: 0 - m_PreserveAspect: 1 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 2 --- !u!222 &222000010186370168 CanvasRenderer: m_ObjectHideFlags: 1 @@ -1853,30 +809,6 @@ CanvasRenderer: m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1000014088439944} ---- !u!222 &222227951865979474 -CanvasRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1619517534170012} ---- !u!222 &222582790420601646 -CanvasRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1141551173516660} ---- !u!222 &222928571895566388 -CanvasRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1036881825388254} ---- !u!222 &222975643046639372 -CanvasRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1430967031119936} --- !u!223 &223000010278076522 Canvas: m_ObjectHideFlags: 1 @@ -1897,46 +829,6 @@ Canvas: m_SortingLayerID: 0 m_SortingOrder: 0 m_TargetDisplay: 0 ---- !u!223 &223499351256631318 -Canvas: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1411372913666494} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 2 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 25 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!223 &223502477285382174 -Canvas: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1603094234734992} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 2 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 25 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 --- !u!224 &224000011129790424 RectTransform: m_ObjectHideFlags: 1 @@ -2107,192 +999,6 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224107373598291132 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1365241548943880} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.425, y: 0.5000001, z: 0.42500013} - m_Children: [] - m_Father: {fileID: 4670339961100958} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 100, y: 100} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224124519857189990 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1603094234734992} - m_LocalRotation: {x: 1, y: -0, z: -0, w: 0} - m_LocalPosition: {x: 0, y: 0, z: 0.00093460095} - m_LocalScale: {x: 0.85, y: 0.85000026, z: 0.13000003} - m_Children: - - {fileID: 4940108482629240} - m_Father: {fileID: 4670339961100958} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: -0.0000012314413} - m_SizeDelta: {x: 100, y: 100} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224333717671022096 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1167948277449984} - m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.425, y: 0.5000001, z: 0.42500013} - m_Children: [] - m_Father: {fileID: 4796074920551568} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 100, y: 100} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224388597326433990 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1619517534170012} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -0.00000013453973} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 224878234700512394} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: -24.5, y: -24.5} - m_AnchorMax: {x: 25.5, y: 25.5} - m_AnchoredPosition: {x: -0.00000032782555, y: 0.00000014901161} - m_SizeDelta: {x: -1.13105, y: -1.13086} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224393326463988594 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1036881825388254} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -0.00000013408862} - m_LocalScale: {x: 0.00008, y: 0.00008, z: 1} - m_Children: [] - m_Father: {fileID: 224939432255965946} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0.00008, y: 0.0005000001} - m_SizeDelta: {x: 268.38452, y: 268.38452} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224638576672757326 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1430967031119936} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -0.00000013453973} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 224939432255965946} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: -24.5, y: -24.5} - m_AnchorMax: {x: 25.5, y: 25.5} - m_AnchoredPosition: {x: -0.00000032782555, y: 0.00000014901161} - m_SizeDelta: {x: -1.13105, y: -1.13086} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224860733548256162 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1411372913666494} - m_LocalRotation: {x: 1, y: -0, z: -0, w: 0} - m_LocalPosition: {x: 0, y: 0, z: 0.00093460095} - m_LocalScale: {x: 0.85, y: 0.85000026, z: 0.13000003} - m_Children: - - {fileID: 4572708185800628} - m_Father: {fileID: 4796074920551568} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: -0.0000012314413} - m_SizeDelta: {x: 100, y: 100} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224878234700512394 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1887300028592862} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 224388597326433990} - - {fileID: 224963898299502848} - m_Father: {fileID: 4940108482629240} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: -8.731149e-10, y: -2.3283064e-10} - m_SizeDelta: {x: 0.02307, y: 0.02307} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224939432255965946 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1482568457756204} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 224638576672757326} - - {fileID: 224393326463988594} - m_Father: {fileID: 4572708185800628} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: -8.731149e-10, y: -2.3283064e-10} - m_SizeDelta: {x: 0.02307, y: 0.02307} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!224 &224963898299502848 -RectTransform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1141551173516660} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -0.00000013408862} - m_LocalScale: {x: 0.00008, y: 0.00008, z: 1} - m_Children: [] - m_Father: {fileID: 224878234700512394} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0.00008, y: 0.0005000001} - m_SizeDelta: {x: 268.38452, y: 268.38452} - m_Pivot: {x: 0.5, y: 0.5} --- !u!225 &225000012229749264 CanvasGroup: m_ObjectHideFlags: 1 @@ -2304,25 +1010,3 @@ CanvasGroup: m_Interactable: 0 m_BlocksRaycasts: 0 m_IgnoreParentGroups: 0 ---- !u!225 &225328779711015670 -CanvasGroup: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1603094234734992} - m_Enabled: 1 - m_Alpha: 1 - m_Interactable: 1 - m_BlocksRaycasts: 0 - m_IgnoreParentGroups: 0 ---- !u!225 &225914373114193260 -CanvasGroup: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1411372913666494} - m_Enabled: 1 - m_Alpha: 1 - m_Interactable: 1 - m_BlocksRaycasts: 0 - m_IgnoreParentGroups: 0 diff --git a/Tools/AnnotationTool/Prefabs/SettingsUI.prefab b/Tools/AnnotationTool/Prefabs/SettingsUI.prefab index 0d10682ad..2e4c565b4 100644 --- a/Tools/AnnotationTool/Prefabs/SettingsUI.prefab +++ b/Tools/AnnotationTool/Prefabs/SettingsUI.prefab @@ -20,7 +20,7 @@ GameObject: m_Component: - component: {fileID: 224000012653929454} - component: {fileID: 222000012891014098} - - component: {fileID: 114000012025195674} + - component: {fileID: 114693843284214446} m_Layer: 5 m_Name: Label m_TagString: Untagged @@ -54,7 +54,7 @@ GameObject: m_Component: - component: {fileID: 224000011405639814} - component: {fileID: 222000011416400564} - - component: {fileID: 114000011583981380} + - component: {fileID: 114537424663619190} m_Layer: 5 m_Name: Label m_TagString: Untagged @@ -190,7 +190,7 @@ GameObject: m_Component: - component: {fileID: 224874559224435002} - component: {fileID: 222817483957468890} - - component: {fileID: 114210595956423184} + - component: {fileID: 114187873217472778} m_Layer: 5 m_Name: Text m_TagString: Untagged @@ -252,39 +252,6 @@ MonoBehaviour: m_FillAmount: 1 m_FillClockwise: 1 m_FillOrigin: 0 ---- !u!114 &114000011583981380 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000011512978662} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 20 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Mesh --- !u!114 &114000011835530144 MonoBehaviour: m_ObjectHideFlags: 1 @@ -357,39 +324,6 @@ MonoBehaviour: m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_IsOn: 0 ---- !u!114 &114000012025195674 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000010398065086} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 20 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Transform --- !u!114 &114000012940195592 MonoBehaviour: m_ObjectHideFlags: 1 @@ -496,7 +430,7 @@ MonoBehaviour: m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_IsOn: 1 ---- !u!114 &114210595956423184 +--- !u!114 &114187873217472778 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} @@ -504,10 +438,10 @@ MonoBehaviour: m_GameObject: {fileID: 1123566551031880} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} m_Name: m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} + m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 m_OnCullStateChanged: @@ -515,20 +449,99 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 280 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ' Annotation Grouping Mode:' + m_text: ' Annotation Grouping Mode:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 14 + m_fontSizeBase: 14 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 257 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 114187873217472778} + characterCount: 27 + spriteCount: 0 + spaceCount: 4 + wordCount: 4 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &114261882201029984 MonoBehaviour: m_ObjectHideFlags: 1 @@ -541,6 +554,118 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_DefaultToggle: {fileID: 114000013714903302} +--- !u!114 &114537424663619190 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011512978662} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: Mesh + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 514 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 114537424663619190} + characterCount: 4 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &114691388261995722 MonoBehaviour: m_ObjectHideFlags: 1 @@ -563,6 +688,118 @@ MonoBehaviour: m_ChildForceExpandHeight: 1 m_ChildControlWidth: 1 m_ChildControlHeight: 0 +--- !u!114 &114693843284214446 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000010398065086} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: Transform + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 514 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 114693843284214446} + characterCount: 9 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!222 &222000010570603678 CanvasRenderer: m_ObjectHideFlags: 1 @@ -671,8 +908,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -0.25, y: 0} - m_SizeDelta: {x: -0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000011444372664 RectTransform: @@ -768,8 +1005,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0.25, y: 0} - m_SizeDelta: {x: -0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000013716393632 RectTransform: diff --git a/Tools/AnnotationTool/UserInterface/BrushSizeUI.cs b/Tools/AnnotationTool/UserInterface/BrushSizeUI.cs index e59eda476..9e159d863 100644 --- a/Tools/AnnotationTool/UserInterface/BrushSizeUI.cs +++ b/Tools/AnnotationTool/UserInterface/BrushSizeUI.cs @@ -1,60 +1,83 @@ -#if UNITY_EDITOR -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using UnityEngine.UI; - -public class BrushSizeUI : MonoBehaviour -{ - const float k_MinSize = 0.625f; - const float k_MaxSize = 12.5f; - - [SerializeField] - RectTransform m_SliderHandle; - - [SerializeField] - Slider m_Slider; - - Image m_SliderHandleImage; - - public Action onValueChanged { private get; set; } - - void Awake() - { - // We record property modifications on creation and modification of these UI elements, which will look odd when undone - Undo.postprocessModifications += PostProcessModifications; - m_SliderHandleImage = m_SliderHandle.GetComponent(); - } - - UndoPropertyModification[] PostProcessModifications(UndoPropertyModification[] modifications) - { - var modificationList = new List(modifications); - foreach (var modification in modifications) - { - if (modification.currentValue.target == m_SliderHandle) - modificationList.Remove(modification); - } - - return modificationList.ToArray(); - } - - public void OnSliderValueChanged(float value) - { - m_SliderHandle.localScale = Vector3.one * Mathf.Lerp(k_MinSize, k_MaxSize, value); - - if (onValueChanged != null) - onValueChanged(value); - } - - public void ChangeSliderValue(float newValue) - { - m_Slider.value = newValue; - } - - public void OnBrushColorChanged(Color newColor) - { - m_SliderHandleImage.color = newColor; - } -} -#endif +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using UnityEditor.Experimental.EditorVR.Menus; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.Experimental.EditorVR.Tools +{ + public class BrushSizeUI : MonoBehaviour, IAlternateMenu + { + const float k_MinSize = 0.625f; + const float k_MaxSize = 12.5f; + + [SerializeField] + RectTransform m_SliderHandle; + + [SerializeField] + Slider m_Slider; + + Image m_SliderHandleImage; + MenuHideFlags m_MenuHideFlags; + + public Action onValueChanged { private get; set; } + public Bounds localBounds { get; private set; } + public Transform rayOrigin { get; set; } + + public MenuHideFlags menuHideFlags { + get { return m_MenuHideFlags; } + set + { + if (m_MenuHideFlags == value) + return; + + m_MenuHideFlags = value; + gameObject.SetActive(m_MenuHideFlags == 0); + } + } + + public GameObject menuContent { get { return gameObject; } } + public int priority { get { return 2; } } + + void Awake() + { + localBounds = ObjectUtils.GetBounds(transform); + // We record property modifications on creation and modification of these UI elements, which will look odd when undone + Undo.postprocessModifications += PostProcessModifications; + m_SliderHandleImage = m_SliderHandle.GetComponent(); + } + + UndoPropertyModification[] PostProcessModifications(UndoPropertyModification[] modifications) + { + var modificationList = new List(modifications); + foreach (var modification in modifications) + { + if (modification.currentValue.target == m_SliderHandle) + modificationList.Remove(modification); + } + + return modificationList.ToArray(); + } + + public void OnSliderValueChanged(float value) + { + m_SliderHandle.localScale = Vector3.one * Mathf.Lerp(k_MinSize, k_MaxSize, value); + + if (onValueChanged != null) + onValueChanged(value); + } + + public void ChangeSliderValue(float newValue) + { + m_Slider.value = newValue; + } + + public void OnBrushColorChanged(Color newColor) + { + m_SliderHandleImage.color = newColor; + } + } +} +#endif diff --git a/Tools/AnnotationTool/UserInterface/ColorPickerActivator.cs b/Tools/AnnotationTool/UserInterface/ColorPickerActivator.cs index d49c5b413..d66f51b61 100644 --- a/Tools/AnnotationTool/UserInterface/ColorPickerActivator.cs +++ b/Tools/AnnotationTool/UserInterface/ColorPickerActivator.cs @@ -1,111 +1,69 @@ -#if UNITY_EDITOR -using System; -using System.Collections; -using UnityEditor.Experimental.EditorVR; -using UnityEditor.Experimental.EditorVR.Extensions; -using UnityEditor.Experimental.EditorVR.UI; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; -using UnityEngine.EventSystems; - -public class ColorPickerActivator : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler -{ - [SerializeField] - Transform m_TargetScale; - - [SerializeField] - Transform m_Icon; - - [SerializeField] - GameObject m_Undo; - - [SerializeField] - GameObject m_Redo; - - [SerializeField] - float m_PickerOffset = 0.045f; - - Coroutine m_HighlightCoroutine; - GradientButton m_UndoButton; - GradientButton m_RedoButton; - - public Transform rayOrigin { private get; set; } - public Action showColorPicker { private get; set; } - public Action hideColorPicker { private get; set; } - public Node node { private get; set; } - - public event Action undoButtonClick - { - add { m_UndoButton.click += value; } - remove { m_UndoButton.click -= value; } - } - - public event Action redoButtonClick - { - add { m_RedoButton.click += value; } - remove { m_RedoButton.click -= value; } - } - - void Awake() - { - m_UndoButton = m_Undo.GetComponentInChildren(); - m_UndoButton.normalGradientPair = UnityBrandColorScheme.grayscaleSessionGradient; - m_UndoButton.highlightGradientPair = UnityBrandColorScheme.sessionGradient; - m_RedoButton = m_Redo.GetComponentInChildren(); - m_RedoButton.normalGradientPair = UnityBrandColorScheme.grayscaleSessionGradient; - m_RedoButton.highlightGradientPair = UnityBrandColorScheme.sessionGradient; - } - - void Start() - { - m_UndoButton.UpdateMaterialColors(); - m_RedoButton.UpdateMaterialColors(); - } - - public void OnPointerClick(PointerEventData eventData) - { - eventData.Use(); - } - - public void OnPointerEnter(PointerEventData eventData) - { - showColorPicker(rayOrigin); - this.RestartCoroutine(ref m_HighlightCoroutine, Highlight(true)); - - m_Undo.SetActive(false); - m_Redo.SetActive(false); - - eventData.Use(); - } - - public void OnPointerExit(PointerEventData eventData) - { - hideColorPicker(); - this.RestartCoroutine(ref m_HighlightCoroutine, Highlight(false)); - - m_Undo.SetActive(true); - m_Redo.SetActive(true); - } - - IEnumerator Highlight(bool transitionIn) - { - var amount = 0f; - var currentScale = m_Icon.localScale; - var targetScale = transitionIn ? m_TargetScale.localScale : Vector3.one; - var currentPosition = m_Icon.localPosition; - var targetPosition = transitionIn ? (node == Node.LeftHand ? Vector3.left : Vector3.right) * m_PickerOffset : Vector3.zero; - var speed = (currentScale.x + 0.5f / targetScale.x) * 4; - - while (amount < 1f) - { - amount += Time.unscaledDeltaTime * speed; - var t = Mathf.SmoothStep(0f, 1f, amount); - m_Icon.localScale = Vector3.Lerp(currentScale, targetScale, t); - m_Icon.localPosition = Vector3.Lerp(currentPosition, targetPosition, t); - yield return null; - } - - m_Icon.localScale = targetScale; - } -} -#endif +#if UNITY_EDITOR +using System; +using System.Collections; +using UnityEditor.Experimental.EditorVR.Extensions; +using UnityEngine; +using UnityEngine.EventSystems; + +namespace UnityEditor.Experimental.EditorVR.Tools +{ + public class ColorPickerActivator : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler + { + [SerializeField] + Transform m_TargetScale; + + [SerializeField] + Transform m_Icon; + + [SerializeField] + float m_PickerOffset = 0.045f; + + Coroutine m_HighlightCoroutine; + + public Transform rayOrigin { private get; set; } + public Action showColorPicker { private get; set; } + public Action hideColorPicker { private get; set; } + public Node node { private get; set; } + + public void OnPointerClick(PointerEventData eventData) + { + eventData.Use(); + } + + public void OnPointerEnter(PointerEventData eventData) + { + showColorPicker(rayOrigin); + this.RestartCoroutine(ref m_HighlightCoroutine, Highlight(true)); + + eventData.Use(); + } + + public void OnPointerExit(PointerEventData eventData) + { + hideColorPicker(); + this.RestartCoroutine(ref m_HighlightCoroutine, Highlight(false)); + } + + IEnumerator Highlight(bool transitionIn) + { + var amount = 0f; + var currentScale = m_Icon.localScale; + var targetScale = transitionIn ? m_TargetScale.localScale : Vector3.one; + var currentPosition = m_Icon.localPosition; + var targetPosition = transitionIn ? (node == Node.LeftHand ? Vector3.left : Vector3.right) * m_PickerOffset : Vector3.zero; + var speed = (currentScale.x + 0.5f / targetScale.x) * 4; + + while (amount < 1f) + { + amount += Time.unscaledDeltaTime * speed; + var t = Mathf.SmoothStep(0f, 1f, amount); + m_Icon.localScale = Vector3.Lerp(currentScale, targetScale, t); + m_Icon.localPosition = Vector3.Lerp(currentPosition, targetPosition, t); + yield return null; + } + + m_Icon.localScale = targetScale; + } + } +} +#endif diff --git a/Tools/AnnotationTool/UserInterface/ColorPickerSquareUI.cs b/Tools/AnnotationTool/UserInterface/ColorPickerSquareUI.cs index 6c618ac1f..dfb29f6c5 100644 --- a/Tools/AnnotationTool/UserInterface/ColorPickerSquareUI.cs +++ b/Tools/AnnotationTool/UserInterface/ColorPickerSquareUI.cs @@ -1,28 +1,31 @@ -#if UNITY_EDITOR -using System; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -public class ColorPickerSquareUI : Selectable, IDragHandler, IBeginDragHandler, IEndDragHandler -{ - bool m_AllowDragEvents; - - public Action onDrag { private get; set; } - - public void OnBeginDrag(PointerEventData eventData) - { - m_AllowDragEvents = true; - } - - public void OnDrag(PointerEventData eventData) - { - if (onDrag != null && m_AllowDragEvents) - onDrag(); - } - - public void OnEndDrag(PointerEventData eventData) - { - m_AllowDragEvents = false; - } -} -#endif +#if UNITY_EDITOR +using System; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +namespace UnityEditor.Experimental.EditorVR.Tools +{ + public class ColorPickerSquareUI : Selectable, IDragHandler, IBeginDragHandler, IEndDragHandler + { + bool m_AllowDragEvents; + + public Action onDrag { private get; set; } + + public void OnBeginDrag(PointerEventData eventData) + { + m_AllowDragEvents = true; + } + + public void OnDrag(PointerEventData eventData) + { + if (onDrag != null && m_AllowDragEvents) + onDrag(); + } + + public void OnEndDrag(PointerEventData eventData) + { + m_AllowDragEvents = false; + } + } +} +#endif diff --git a/Tools/AnnotationTool/UserInterface/ColorPickerUI.cs b/Tools/AnnotationTool/UserInterface/ColorPickerUI.cs index da1fb9599..b152aee9c 100644 --- a/Tools/AnnotationTool/UserInterface/ColorPickerUI.cs +++ b/Tools/AnnotationTool/UserInterface/ColorPickerUI.cs @@ -1,183 +1,186 @@ -#if UNITY_EDITOR -using UnityEngine; -using System.Collections; -using UnityEngine.UI; -using System; -using UnityEditor.Experimental.EditorVR.Extensions; -using UnityEngine.EventSystems; - -public class ColorPickerUI : MonoBehaviour, IPointerExitHandler -{ - [SerializeField] - float m_FadeTime; - - [SerializeField] - RawImage m_ColorPicker; - - [SerializeField] - RawImage m_SliderBackground; - - [SerializeField] - RectTransform m_Picker; - - [SerializeField] - RectTransform m_PickerBounds; - - [SerializeField] - ColorPickerSquareUI m_ColorPickerSquare; - - Vector3 m_PickerTargetPosition; - - Texture2D m_BrightnessBarTexture; - Texture2D m_ColorPickerTexture; - - Coroutine m_FadeCoroutine; - - public Transform toolRayOrigin { private get; set; } - - public Action onColorPicked { private get; set; } - - public Action onHideCalled { private get; set; } - - void Start() - { - m_ColorPickerSquare.onDrag = OnDrag; - - m_ColorPickerTexture = m_ColorPickerSquare.GetComponent().texture as Texture2D; - GenerateBrightnessBar(); - } - - void OnDestroy() - { - DestroyImmediate(m_BrightnessBarTexture); - } - - void Update() - { - m_Picker.localPosition = m_PickerTargetPosition; - } - - public void Show() - { - this.RestartCoroutine(ref m_FadeCoroutine, FadeCanvas(false)); - } - - public void Hide() - { - this.RestartCoroutine(ref m_FadeCoroutine, FadeCanvas(true)); - } - - public void OnSliderChanged(float val) - { - m_ColorPicker.color = Color.Lerp(Color.black, Color.white, val); - PositionToColor(); - } - - IEnumerator FadeCanvas(bool fadeOut) - { - enabled = !fadeOut; - m_Picker.localPosition = m_PickerTargetPosition; - - var canvasGroup = GetComponentInChildren(); - var current = canvasGroup.alpha; - var start = fadeOut ? 1 : 0; - var target = 1 - start; - - if (current == target) - yield break; - - var ratio = fadeOut ? 1 - current : current; - while (ratio < 1) - { - canvasGroup.alpha = Mathf.Lerp(start, target, ratio); - ratio += Time.unscaledDeltaTime / m_FadeTime; - yield return null; - } - - GetComponentInChildren().enabled = !fadeOut; - m_Picker.gameObject.SetActive(!fadeOut); - canvasGroup.alpha = target; - canvasGroup.interactable = !fadeOut; - canvasGroup.blocksRaycasts = !fadeOut; - } - - void OnDrag() - { - if (toolRayOrigin && enabled) - { - var worldToLocal = m_ColorPicker.rectTransform.worldToLocalMatrix; - var rect = m_ColorPicker.rectTransform.rect; - - var localRayPos = worldToLocal.MultiplyPoint3x4(toolRayOrigin.position); - var localRayForward = worldToLocal.MultiplyVector(toolRayOrigin.forward).normalized; - - var height = localRayPos.z; - var angle = Vector3.Angle(new Vector3(0, 0, height), localRayForward); - var sine = Mathf.Sin((90 - angle) * Mathf.Deg2Rad); - - var distance = Mathf.Abs(height / sine); - var point = localRayPos + localRayForward * distance; - point = point.normalized * Mathf.Min(point.magnitude, rect.width / 2f); - - m_PickerTargetPosition = point; - GenerateBrightnessBar(); - PositionToColor(); - } - } - - void GenerateBrightnessBar() - { - var rect = m_SliderBackground.rectTransform.rect; - if (!m_BrightnessBarTexture) - m_BrightnessBarTexture = new Texture2D((int)rect.width, 1); - - var col = GetColorForCurrentPosition(); - - for (var y = 0; y < m_BrightnessBarTexture.height; y++) - { - for (var x = 0; x < m_BrightnessBarTexture.width; x++) - { - var brightness = x / rect.width; - var tempCol = col * brightness; - tempCol.a = 1; - m_BrightnessBarTexture.SetPixel(x, y, tempCol); - } - } - m_BrightnessBarTexture.Apply(); - - m_SliderBackground.texture = m_BrightnessBarTexture; - } - - void PositionToColor() - { - if (onColorPicked != null) - { - var col = GetColorForCurrentPosition(); - col *= m_ColorPicker.color; // Apply brightness slider - onColorPicked(col); - } - } - - Color GetColorForCurrentPosition() - { - var rect = m_PickerBounds.rect; - - var position = m_PickerTargetPosition; - - position.x = (position.x + rect.width * 0.5f) / rect.width; - position.y = (position.y + rect.height * 0.5f) / rect.height; - - var textureX = (int)(position.x * m_ColorPickerTexture.width); - var textureY = (int)(position.y * m_ColorPickerTexture.height); - var col = m_ColorPickerTexture.GetPixel(textureX, textureY); - - return col; - } - - public void OnPointerExit(PointerEventData eventData) - { - if (onHideCalled != null) - onHideCalled(); - } -} -#endif +#if UNITY_EDITOR +using UnityEngine; +using System.Collections; +using UnityEngine.UI; +using System; +using UnityEditor.Experimental.EditorVR.Extensions; +using UnityEngine.EventSystems; + +namespace UnityEditor.Experimental.EditorVR.Tools +{ + public class ColorPickerUI : MonoBehaviour, IPointerExitHandler + { + [SerializeField] + float m_FadeTime; + + [SerializeField] + RawImage m_ColorPicker; + + [SerializeField] + RawImage m_SliderBackground; + + [SerializeField] + RectTransform m_Picker; + + [SerializeField] + RectTransform m_PickerBounds; + + [SerializeField] + ColorPickerSquareUI m_ColorPickerSquare; + + Vector3 m_PickerTargetPosition; + + Texture2D m_BrightnessBarTexture; + Texture2D m_ColorPickerTexture; + + Coroutine m_FadeCoroutine; + + public Transform toolRayOrigin { private get; set; } + + public Action onColorPicked { private get; set; } + + public Action onHideCalled { private get; set; } + + void Start() + { + m_ColorPickerSquare.onDrag = OnDrag; + + m_ColorPickerTexture = m_ColorPickerSquare.GetComponent().texture as Texture2D; + GenerateBrightnessBar(); + } + + void OnDestroy() + { + DestroyImmediate(m_BrightnessBarTexture); + } + + void Update() + { + m_Picker.localPosition = m_PickerTargetPosition; + } + + public void Show() + { + this.RestartCoroutine(ref m_FadeCoroutine, FadeCanvas(false)); + } + + public void Hide() + { + this.RestartCoroutine(ref m_FadeCoroutine, FadeCanvas(true)); + } + + public void OnSliderChanged(float val) + { + m_ColorPicker.color = Color.Lerp(Color.black, Color.white, val); + PositionToColor(); + } + + IEnumerator FadeCanvas(bool fadeOut) + { + enabled = !fadeOut; + m_Picker.localPosition = m_PickerTargetPosition; + + var canvasGroup = GetComponentInChildren(); + var current = canvasGroup.alpha; + var start = fadeOut ? 1 : 0; + var target = 1 - start; + + if (current == target) + yield break; + + var ratio = fadeOut ? 1 - current : current; + while (ratio < 1) + { + canvasGroup.alpha = Mathf.Lerp(start, target, ratio); + ratio += Time.unscaledDeltaTime / m_FadeTime; + yield return null; + } + + GetComponentInChildren().enabled = !fadeOut; + m_Picker.gameObject.SetActive(!fadeOut); + canvasGroup.alpha = target; + canvasGroup.interactable = !fadeOut; + canvasGroup.blocksRaycasts = !fadeOut; + } + + void OnDrag() + { + if (toolRayOrigin && enabled) + { + var worldToLocal = m_ColorPicker.rectTransform.worldToLocalMatrix; + var rect = m_ColorPicker.rectTransform.rect; + + var localRayPos = worldToLocal.MultiplyPoint3x4(toolRayOrigin.position); + var localRayForward = worldToLocal.MultiplyVector(toolRayOrigin.forward).normalized; + + var height = localRayPos.z; + var angle = Vector3.Angle(new Vector3(0, 0, height), localRayForward); + var sine = Mathf.Sin((90 - angle) * Mathf.Deg2Rad); + + var distance = Mathf.Abs(height / sine); + var point = localRayPos + localRayForward * distance; + point = point.normalized * Mathf.Min(point.magnitude, rect.width / 2f); + + m_PickerTargetPosition = point; + GenerateBrightnessBar(); + PositionToColor(); + } + } + + void GenerateBrightnessBar() + { + var rect = m_SliderBackground.rectTransform.rect; + if (!m_BrightnessBarTexture) + m_BrightnessBarTexture = new Texture2D((int)rect.width, 1); + + var col = GetColorForCurrentPosition(); + + for (var y = 0; y < m_BrightnessBarTexture.height; y++) + { + for (var x = 0; x < m_BrightnessBarTexture.width; x++) + { + var brightness = x / rect.width; + var tempCol = col * brightness; + tempCol.a = 1; + m_BrightnessBarTexture.SetPixel(x, y, tempCol); + } + } + m_BrightnessBarTexture.Apply(); + + m_SliderBackground.texture = m_BrightnessBarTexture; + } + + void PositionToColor() + { + if (onColorPicked != null) + { + var col = GetColorForCurrentPosition(); + col *= m_ColorPicker.color; // Apply brightness slider + onColorPicked(col); + } + } + + Color GetColorForCurrentPosition() + { + var rect = m_PickerBounds.rect; + + var position = m_PickerTargetPosition; + + position.x = (position.x + rect.width * 0.5f) / rect.width; + position.y = (position.y + rect.height * 0.5f) / rect.height; + + var textureX = (int)(position.x * m_ColorPickerTexture.width); + var textureY = (int)(position.y * m_ColorPickerTexture.height); + var col = m_ColorPickerTexture.GetPixel(textureX, textureY); + + return col; + } + + public void OnPointerExit(PointerEventData eventData) + { + if (onHideCalled != null) + onHideCalled(); + } + } +} +#endif diff --git a/Tools/CreatePrimitiveTool/CreatePrimitiveMenu.cs b/Tools/CreatePrimitiveTool/CreatePrimitiveMenu.cs index 829afbe9f..783110e7b 100644 --- a/Tools/CreatePrimitiveTool/CreatePrimitiveMenu.cs +++ b/Tools/CreatePrimitiveTool/CreatePrimitiveMenu.cs @@ -1,58 +1,59 @@ -#if UNITY_EDITOR -using System; -using UnityEditor.Experimental.EditorVR.Menus; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; - -namespace UnityEditor.Experimental.EditorVR.Tools -{ - sealed class CreatePrimitiveMenu : MonoBehaviour, IMenu - { - [SerializeField] - GameObject[] m_HighlightObjects; - - public Action selectPrimitive; - public Action close; - - public Bounds localBounds { get; private set; } - - public MenuHideFlags menuHideFlags - { - get { return gameObject.activeSelf ? 0 : MenuHideFlags.Hidden; } - set { gameObject.SetActive(value == 0); } - } - - public GameObject menuContent { get { return gameObject; } } - - void Awake() - { - localBounds = ObjectUtils.GetBounds(transform); - } - - public void SelectPrimitive(int type) - { - selectPrimitive((PrimitiveType)type, false); - - // the order of the objects in m_HighlightObjects is matched to the values of the PrimitiveType enum elements - for (var i = 0; i < m_HighlightObjects.Length; i++) - { - var go = m_HighlightObjects[i]; - go.SetActive(i == type); - } - } - - public void SelectFreeformCuboid() - { - selectPrimitive(PrimitiveType.Cube, true); - - foreach (var go in m_HighlightObjects) - go.SetActive(false); - } - - public void Close() - { - close(); - } - } -} -#endif +#if UNITY_EDITOR +using System; +using UnityEditor.Experimental.EditorVR.Menus; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; + +namespace UnityEditor.Experimental.EditorVR.Tools +{ + sealed class CreatePrimitiveMenu : MonoBehaviour, IMenu + { + [SerializeField] + GameObject[] m_HighlightObjects; + + public Action selectPrimitive; + public Action close; + + public Bounds localBounds { get; private set; } + public int priority { get { return 1; } } + + public MenuHideFlags menuHideFlags + { + get { return gameObject.activeSelf ? 0 : MenuHideFlags.Hidden; } + set { gameObject.SetActive(value == 0); } + } + + public GameObject menuContent { get { return gameObject; } } + + void Awake() + { + localBounds = ObjectUtils.GetBounds(transform); + } + + public void SelectPrimitive(int type) + { + selectPrimitive((PrimitiveType)type, false); + + // the order of the objects in m_HighlightObjects is matched to the values of the PrimitiveType enum elements + for (var i = 0; i < m_HighlightObjects.Length; i++) + { + var go = m_HighlightObjects[i]; + go.SetActive(i == type); + } + } + + public void SelectFreeformCuboid() + { + selectPrimitive(PrimitiveType.Cube, true); + + foreach (var go in m_HighlightObjects) + go.SetActive(false); + } + + public void Close() + { + close(); + } + } +} +#endif diff --git a/Tools/CreatePrimitiveTool/CreatePrimitiveTool.cs b/Tools/CreatePrimitiveTool/CreatePrimitiveTool.cs index 86400d51a..fdad93d1d 100644 --- a/Tools/CreatePrimitiveTool/CreatePrimitiveTool.cs +++ b/Tools/CreatePrimitiveTool/CreatePrimitiveTool.cs @@ -1,197 +1,199 @@ -#if UNITY_EDITOR -using System.Collections.Generic; -using UnityEditor.Experimental.EditorVR.Proxies; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; -using UnityEngine.InputNew; - -namespace UnityEditor.Experimental.EditorVR.Tools -{ - [MainMenuItem("Primitive", "Create", "Create primitives in the scene")] - sealed class CreatePrimitiveTool : MonoBehaviour, ITool, IStandardActionMap, IConnectInterfaces, IInstantiateMenuUI, - IUsesRayOrigin, IUsesSpatialHash, IUsesViewerScale, ISelectTool, IIsHoveringOverUI, IIsMainMenuVisible, - IRayVisibilitySettings, IMenuIcon, IRequestFeedback, IUsesNode - { - [SerializeField] - CreatePrimitiveMenu m_MenuPrefab; - - [SerializeField] - Sprite m_Icon; - - const float k_DrawDistance = 0.075f; - - GameObject m_ToolMenu; - - PrimitiveType m_SelectedPrimitiveType = PrimitiveType.Cube; - bool m_Freeform; - - GameObject m_CurrentGameObject; - - Vector3 m_StartPoint = Vector3.zero; - Vector3 m_EndPoint = Vector3.zero; - - PrimitiveCreationStates m_State = PrimitiveCreationStates.StartPoint; - - public Transform rayOrigin { get; set; } - public Node node { get; set; } - - public Sprite icon { get { return m_Icon; } } - - enum PrimitiveCreationStates - { - StartPoint, - EndPoint, - Freeform - } - - void Start() - { - // Clear selection so we can't manipulate things - Selection.activeGameObject = null; - - m_ToolMenu = this.InstantiateMenuUI(rayOrigin, m_MenuPrefab); - var createPrimitiveMenu = m_ToolMenu.GetComponent(); - this.ConnectInterfaces(createPrimitiveMenu, rayOrigin); - createPrimitiveMenu.selectPrimitive = SetSelectedPrimitive; - createPrimitiveMenu.close = Close; - - var controls = new BindingDictionary(); - InputUtils.GetBindingDictionaryFromActionMap(standardActionMap, controls); - - foreach (var control in controls) - { - foreach (var id in control.Value) - { - var request = (ProxyFeedbackRequest)this.GetFeedbackRequestObject(typeof(ProxyFeedbackRequest)); - request.node = node; - request.control = id; - request.tooltipText = "Draw"; - this.AddFeedbackRequest(request); - } - } - } - - public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeControl) - { - if (!IsActive()) - return; - - var standardInput = (Standard)input; - - switch (m_State) - { - case PrimitiveCreationStates.StartPoint: - { - HandleStartPoint(standardInput, consumeControl); - break; - } - case PrimitiveCreationStates.EndPoint: - { - UpdatePositions(); - SetScalingForObjectType(); - CheckForTriggerRelease(standardInput, consumeControl); - break; - } - case PrimitiveCreationStates.Freeform: - { - UpdatePositions(); - UpdateFreeformScale(); - CheckForTriggerRelease(standardInput, consumeControl); - break; - } - } - - if (m_State == PrimitiveCreationStates.StartPoint && this.IsHoveringOverUI(rayOrigin)) - this.RemoveRayVisibilitySettings(rayOrigin, this); - else - this.AddRayVisibilitySettings(rayOrigin, this, false, true); - } - - void SetSelectedPrimitive(PrimitiveType type, bool isFreeform) - { - m_SelectedPrimitiveType = type; - m_Freeform = isFreeform; - } - - void HandleStartPoint(Standard standardInput, ConsumeControlDelegate consumeControl) - { - if (standardInput.action.wasJustPressed) - { - m_CurrentGameObject = GameObject.CreatePrimitive(m_SelectedPrimitiveType); - - // Set starting minimum scale (don't allow zero scale object to be created) - const float kMinScale = 0.0025f; - var viewerScale = this.GetViewerScale(); - m_CurrentGameObject.transform.localScale = Vector3.one * kMinScale * viewerScale; - m_StartPoint = rayOrigin.position + rayOrigin.forward * k_DrawDistance * viewerScale; - m_CurrentGameObject.transform.position = m_StartPoint; - - m_State = m_Freeform ? PrimitiveCreationStates.Freeform : PrimitiveCreationStates.EndPoint; - - this.AddToSpatialHash(m_CurrentGameObject); - - consumeControl(standardInput.action); - Selection.activeGameObject = m_CurrentGameObject; - } - } - - void SetScalingForObjectType() - { - var corner = (m_EndPoint - m_StartPoint).magnitude; - - // it feels better to scale these primitives vertically with the draw point - if (m_SelectedPrimitiveType == PrimitiveType.Capsule || m_SelectedPrimitiveType == PrimitiveType.Cylinder || m_SelectedPrimitiveType == PrimitiveType.Cube) - m_CurrentGameObject.transform.localScale = Vector3.one * corner * 0.5f; - else - m_CurrentGameObject.transform.localScale = Vector3.one * corner; - } - - void UpdatePositions() - { - m_EndPoint = rayOrigin.position + rayOrigin.forward * k_DrawDistance * this.GetViewerScale(); - m_CurrentGameObject.transform.position = (m_StartPoint + m_EndPoint) * 0.5f; - } - - void UpdateFreeformScale() - { - var maxCorner = Vector3.Max(m_StartPoint, m_EndPoint); - var minCorner = Vector3.Min(m_StartPoint, m_EndPoint); - m_CurrentGameObject.transform.localScale = maxCorner - minCorner; - } - - void CheckForTriggerRelease(Standard standardInput, ConsumeControlDelegate consumeControl) - { - // Ready for next object to be created - if (standardInput.action.wasJustReleased) - { - m_State = PrimitiveCreationStates.StartPoint; - - consumeControl(standardInput.action); - } - } - - bool IsActive() - { - return !this.IsMainMenuVisible(rayOrigin); - } - - void Close() - { - this.SelectTool(rayOrigin, GetType()); - } - - void OnDestroy() - { - ObjectUtils.Destroy(m_ToolMenu); - - if (rayOrigin == null) - return; - - this.RemoveRayVisibilitySettings(rayOrigin, this); - this.ClearFeedbackRequests(); - } - - public ActionMap standardActionMap { private get; set; } - } -} -#endif +#if UNITY_EDITOR +using System.Collections.Generic; +using UnityEditor.Experimental.EditorVR.Proxies; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; +using UnityEngine.InputNew; + +namespace UnityEditor.Experimental.EditorVR.Tools +{ + [MainMenuItem("Primitive", "Create", "Create primitives in the scene")] + sealed class CreatePrimitiveTool : MonoBehaviour, ITool, IStandardActionMap, IConnectInterfaces, IInstantiateMenuUI, + IUsesRayOrigin, IUsesSpatialHash, IUsesViewerScale, ISelectTool, IIsHoveringOverUI, IIsMainMenuVisible, + IRayVisibilitySettings, IMenuIcon, IRequestFeedback, IUsesNode + { + [SerializeField] + CreatePrimitiveMenu m_MenuPrefab; + + [SerializeField] + Sprite m_Icon; + + const float k_DrawDistance = 0.075f; + + GameObject m_ToolMenu; + + PrimitiveType m_SelectedPrimitiveType = PrimitiveType.Cube; + bool m_Freeform; + + GameObject m_CurrentGameObject; + + Vector3 m_StartPoint = Vector3.zero; + Vector3 m_EndPoint = Vector3.zero; + + PrimitiveCreationStates m_State = PrimitiveCreationStates.StartPoint; + + public Transform rayOrigin { get; set; } + public Node node { get; set; } + + public Sprite icon { get { return m_Icon; } } + + enum PrimitiveCreationStates + { + StartPoint, + EndPoint, + Freeform + } + + void Start() + { + // Clear selection so we can't manipulate things + Selection.activeGameObject = null; + + m_ToolMenu = this.InstantiateMenuUI(rayOrigin, m_MenuPrefab); + var createPrimitiveMenu = m_ToolMenu.GetComponent(); + this.ConnectInterfaces(createPrimitiveMenu, rayOrigin); + createPrimitiveMenu.selectPrimitive = SetSelectedPrimitive; + createPrimitiveMenu.close = Close; + + var controls = new BindingDictionary(); + InputUtils.GetBindingDictionaryFromActionMap(standardActionMap, controls); + + foreach (var control in controls) + { + foreach (var id in control.Value) + { + var request = (ProxyFeedbackRequest)this.GetFeedbackRequestObject(typeof(ProxyFeedbackRequest)); + request.node = node; + request.control = id; + request.tooltipText = "Draw"; + this.AddFeedbackRequest(request); + } + } + } + + public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeControl) + { + if (!IsActive()) + return; + + var standardInput = (Standard)input; + + switch (m_State) + { + case PrimitiveCreationStates.StartPoint: + { + HandleStartPoint(standardInput, consumeControl); + break; + } + case PrimitiveCreationStates.EndPoint: + { + UpdatePositions(); + SetScalingForObjectType(); + CheckForTriggerRelease(standardInput, consumeControl); + break; + } + case PrimitiveCreationStates.Freeform: + { + UpdatePositions(); + UpdateFreeformScale(); + CheckForTriggerRelease(standardInput, consumeControl); + break; + } + } + + if (m_State == PrimitiveCreationStates.StartPoint && this.IsHoveringOverUI(rayOrigin)) + this.RemoveRayVisibilitySettings(rayOrigin, this); + else + this.AddRayVisibilitySettings(rayOrigin, this, false, true); + } + + void SetSelectedPrimitive(PrimitiveType type, bool isFreeform) + { + m_SelectedPrimitiveType = type; + m_Freeform = isFreeform; + } + + void HandleStartPoint(Standard standardInput, ConsumeControlDelegate consumeControl) + { + if (standardInput.action.wasJustPressed) + { + m_CurrentGameObject = GameObject.CreatePrimitive(m_SelectedPrimitiveType); + Undo.RegisterCreatedObjectUndo(m_CurrentGameObject, "Create Primitive"); + + // Set starting minimum scale (don't allow zero scale object to be created) + const float kMinScale = 0.0025f; + var viewerScale = this.GetViewerScale(); + m_CurrentGameObject.transform.localScale = Vector3.one * kMinScale * viewerScale; + m_StartPoint = rayOrigin.position + rayOrigin.forward * k_DrawDistance * viewerScale; + m_CurrentGameObject.transform.position = m_StartPoint; + + m_State = m_Freeform ? PrimitiveCreationStates.Freeform : PrimitiveCreationStates.EndPoint; + + this.AddToSpatialHash(m_CurrentGameObject); + + consumeControl(standardInput.action); + Selection.activeGameObject = m_CurrentGameObject; + } + } + + void SetScalingForObjectType() + { + var corner = (m_EndPoint - m_StartPoint).magnitude; + + // it feels better to scale these primitives vertically with the draw point + if (m_SelectedPrimitiveType == PrimitiveType.Capsule || m_SelectedPrimitiveType == PrimitiveType.Cylinder || m_SelectedPrimitiveType == PrimitiveType.Cube) + m_CurrentGameObject.transform.localScale = Vector3.one * corner * 0.5f; + else + m_CurrentGameObject.transform.localScale = Vector3.one * corner; + } + + void UpdatePositions() + { + m_EndPoint = rayOrigin.position + rayOrigin.forward * k_DrawDistance * this.GetViewerScale(); + m_CurrentGameObject.transform.position = (m_StartPoint + m_EndPoint) * 0.5f; + } + + void UpdateFreeformScale() + { + var maxCorner = Vector3.Max(m_StartPoint, m_EndPoint); + var minCorner = Vector3.Min(m_StartPoint, m_EndPoint); + m_CurrentGameObject.transform.localScale = maxCorner - minCorner; + } + + void CheckForTriggerRelease(Standard standardInput, ConsumeControlDelegate consumeControl) + { + // Ready for next object to be created + if (standardInput.action.wasJustReleased) + { + m_State = PrimitiveCreationStates.StartPoint; + Undo.IncrementCurrentGroup(); + + consumeControl(standardInput.action); + } + } + + bool IsActive() + { + return !this.IsMainMenuVisible(rayOrigin); + } + + void Close() + { + this.SelectTool(rayOrigin, GetType()); + } + + void OnDestroy() + { + ObjectUtils.Destroy(m_ToolMenu); + + if (rayOrigin == null) + return; + + this.RemoveRayVisibilitySettings(rayOrigin, this); + this.ClearFeedbackRequests(); + } + + public ActionMap standardActionMap { private get; set; } + } +} +#endif diff --git a/Tools/LocomotionTool/LocomotionTool.cs b/Tools/LocomotionTool/LocomotionTool.cs index 2f77c83af..55cd28889 100644 --- a/Tools/LocomotionTool/LocomotionTool.cs +++ b/Tools/LocomotionTool/LocomotionTool.cs @@ -597,6 +597,10 @@ bool DoTwoHandedScaling(ConsumeControlDelegate consumeControl) consumeControl(otherLocomotionInput.horizontal); consumeControl(otherLocomotionInput.vertical); + // Pre-emptively consume thumbstick press to override UndoMenu + consumeControl(m_LocomotionInput.scaleReset); + consumeControl(otherLocomotionInput.scaleReset); + var thisPosition = cameraRig.InverseTransformPoint(rayOrigin.position); var otherRayOrigin = otherLocomotionTool.rayOrigin; var otherPosition = cameraRig.InverseTransformPoint(otherRayOrigin.position); @@ -647,13 +651,9 @@ bool DoTwoHandedScaling(ConsumeControlDelegate consumeControl) var scaleReset = m_LocomotionInput.scaleReset; var scaleResetHeld = scaleReset.isHeld; - if (scaleResetHeld) - consumeControl(scaleReset); var otherScaleReset = otherLocomotionInput.scaleReset; var otherScaleResetHeld = otherScaleReset.isHeld; - if (otherScaleResetHeld) - consumeControl(otherScaleReset); // Press both thumb buttons to reset scale if (scaleResetHeld && otherScaleResetHeld) diff --git a/Tools/LocomotionTool/Prefabs/SettingsUI.prefab b/Tools/LocomotionTool/Prefabs/SettingsUI.prefab index b163c5800..3c214c745 100644 --- a/Tools/LocomotionTool/Prefabs/SettingsUI.prefab +++ b/Tools/LocomotionTool/Prefabs/SettingsUI.prefab @@ -20,7 +20,7 @@ GameObject: m_Component: - component: {fileID: 224000012653929454} - component: {fileID: 222000012891014098} - - component: {fileID: 114000012025195674} + - component: {fileID: 114926923194449542} m_Layer: 5 m_Name: Label m_TagString: Untagged @@ -54,7 +54,7 @@ GameObject: m_Component: - component: {fileID: 224000011405639814} - component: {fileID: 222000011416400564} - - component: {fileID: 114000011583981380} + - component: {fileID: 114251560024549528} m_Layer: 5 m_Name: Label m_TagString: Untagged @@ -71,6 +71,7 @@ GameObject: m_Component: - component: {fileID: 224000010858218954} - component: {fileID: 114000011920048442} + - component: {fileID: 114009511206996632} m_Layer: 5 m_Name: Blink m_TagString: Untagged @@ -121,6 +122,7 @@ GameObject: m_Component: - component: {fileID: 224000011444372664} - component: {fileID: 114000013714903302} + - component: {fileID: 114546748432515818} m_Layer: 5 m_Name: Fly m_TagString: Untagged @@ -190,7 +192,7 @@ GameObject: m_Component: - component: {fileID: 224874559224435002} - component: {fileID: 222817483957468890} - - component: {fileID: 114210595956423184} + - component: {fileID: 114630463904937644} m_Layer: 5 m_Name: Text m_TagString: Untagged @@ -252,39 +254,6 @@ MonoBehaviour: m_FillAmount: 1 m_FillClockwise: 1 m_FillOrigin: 0 ---- !u!114 &114000011583981380 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000011512978662} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 20 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Blink --- !u!114 &114000011835530144 MonoBehaviour: m_ObjectHideFlags: 1 @@ -357,39 +326,6 @@ MonoBehaviour: m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_IsOn: 0 ---- !u!114 &114000012025195674 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000010398065086} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 20 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Fly --- !u!114 &114000012940195592 MonoBehaviour: m_ObjectHideFlags: 1 @@ -496,18 +432,34 @@ MonoBehaviour: m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_IsOn: 1 ---- !u!114 &114210595956423184 +--- !u!114 &114009511206996632 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1123566551031880} + m_GameObject: {fileID: 1000011772923556} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} m_Name: m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114251560024549528} + m_Toggle: {fileID: 114000011920048442} +--- !u!114 &114251560024549528 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011512978662} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 m_OnCullStateChanged: @@ -515,20 +467,99 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 280 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ' Locomotion Mode:' + m_text: Blink + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 514 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 114251560024549528} + characterCount: 5 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &114261882201029984 MonoBehaviour: m_ObjectHideFlags: 1 @@ -541,6 +572,134 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_DefaultToggle: {fileID: 114000013714903302} +--- !u!114 &114546748432515818 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013494423478} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114926923194449542} + m_Toggle: {fileID: 114000013714903302} +--- !u!114 &114630463904937644 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1123566551031880} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: ' Locomotion Mode:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 14 + m_fontSizeBase: 14 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 257 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 114630463904937644} + characterCount: 18 + spriteCount: 0 + spaceCount: 3 + wordCount: 3 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &114691388261995722 MonoBehaviour: m_ObjectHideFlags: 1 @@ -563,6 +722,118 @@ MonoBehaviour: m_ChildForceExpandHeight: 1 m_ChildControlWidth: 1 m_ChildControlHeight: 0 +--- !u!114 &114926923194449542 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000010398065086} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: Fly + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 514 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 114926923194449542} + characterCount: 3 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!222 &222000010570603678 CanvasRenderer: m_ObjectHideFlags: 1 @@ -672,7 +943,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -0.5, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000011444372664 RectTransform: @@ -769,7 +1040,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -0.5, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000013716393632 RectTransform: diff --git a/Tools/SelectionTool/Prefabs/SettingsUI.prefab b/Tools/SelectionTool/Prefabs/SettingsUI.prefab index e89bd2e1c..3884c5707 100644 --- a/Tools/SelectionTool/Prefabs/SettingsUI.prefab +++ b/Tools/SelectionTool/Prefabs/SettingsUI.prefab @@ -20,7 +20,7 @@ GameObject: m_Component: - component: {fileID: 224000012653929454} - component: {fileID: 222000012891014098} - - component: {fileID: 114000012025195674} + - component: {fileID: 114872940656036492} m_Layer: 5 m_Name: Label m_TagString: Untagged @@ -54,7 +54,7 @@ GameObject: m_Component: - component: {fileID: 224000011405639814} - component: {fileID: 222000011416400564} - - component: {fileID: 114000011583981380} + - component: {fileID: 114960265468702888} m_Layer: 5 m_Name: Label m_TagString: Untagged @@ -71,6 +71,7 @@ GameObject: m_Component: - component: {fileID: 224000010858218954} - component: {fileID: 114000011920048442} + - component: {fileID: 114098223122120698} m_Layer: 5 m_Name: Sphere m_TagString: Untagged @@ -121,6 +122,7 @@ GameObject: m_Component: - component: {fileID: 224000011444372664} - component: {fileID: 114000013714903302} + - component: {fileID: 114941570635773572} m_Layer: 5 m_Name: Cuboid m_TagString: Untagged @@ -190,7 +192,7 @@ GameObject: m_Component: - component: {fileID: 224874559224435002} - component: {fileID: 222817483957468890} - - component: {fileID: 114210595956423184} + - component: {fileID: 114348078226377316} m_Layer: 5 m_Name: Text m_TagString: Untagged @@ -252,39 +254,6 @@ MonoBehaviour: m_FillAmount: 1 m_FillClockwise: 1 m_FillOrigin: 0 ---- !u!114 &114000011583981380 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000011512978662} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 20 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Sphere --- !u!114 &114000011835530144 MonoBehaviour: m_ObjectHideFlags: 1 @@ -357,39 +326,6 @@ MonoBehaviour: m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_IsOn: 0 ---- !u!114 &114000012025195674 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1000010398065086} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 20 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Cuboid --- !u!114 &114000012940195592 MonoBehaviour: m_ObjectHideFlags: 1 @@ -496,39 +432,22 @@ MonoBehaviour: m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_IsOn: 1 ---- !u!114 &114210595956423184 +--- !u!114 &114098223122120698 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 1123566551031880} + m_GameObject: {fileID: 1000011772923556} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} m_Name: m_EditorClassIdentifier: - m_Material: {fileID: 2100000, guid: dec2d25be9058334c91a0402762efa61, type: 2} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 12800000, guid: 013679fd6ee2085428a7f896aa7b50cc, type: 3} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 280 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ' Block Selection Mode:' + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114960265468702888} + m_Toggle: {fileID: 114000011920048442} --- !u!114 &114261882201029984 MonoBehaviour: m_ObjectHideFlags: 1 @@ -541,6 +460,118 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_DefaultToggle: {fileID: 114000013714903302} +--- !u!114 &114348078226377316 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1123566551031880} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: ' Block Selection Mode:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 14 + m_fontSizeBase: 14 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 257 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 0} + characterCount: 23 + spriteCount: 0 + spaceCount: 4 + wordCount: 4 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &114691388261995722 MonoBehaviour: m_ObjectHideFlags: 1 @@ -563,6 +594,246 @@ MonoBehaviour: m_ChildForceExpandHeight: 1 m_ChildControlWidth: 1 m_ChildControlHeight: 0 +--- !u!114 &114872940656036492 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000010398065086} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: Cuboid + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 514 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 0} + characterCount: 6 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &114941570635773572 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013494423478} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 766c9196b7801da49b40f523eaa556e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ClickPulse: {fileID: 11400000, guid: ad8089d07bd48a047b9d6b45f7a4fd57, type: 2} + m_HoverPulse: {fileID: 11400000, guid: dd561ccb8162d1040adba0a7ea60eadc, type: 2} + m_Description: {fileID: 0} + m_Title: {fileID: 114872940656036492} + m_Toggle: {fileID: 114000013714903302} +--- !u!114 &114960265468702888 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011512978662} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1453722849, guid: 89f0137620f6af44b9ba852b4190e64e, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_text: Sphere + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ea721564999c75441b5b3aa01ae88f76, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: 5be343b145ab9dd42821b06c75f9a60c, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_outlineColor: + serializedVersion: 2 + rgba: 4278190080 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_textAlignment: 514 + m_isAlignmentEnumConverted: 1 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_firstOverflowCharacterIndex: -1 + m_linkedTextComponent: {fileID: 0} + m_isLinkedTextComponent: 0 + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_ignoreRectMaskCulling: 0 + m_ignoreCulling: 1 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_firstVisibleCharacter: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_textInfo: + textComponent: {fileID: 0} + characterCount: 6 + spriteCount: 0 + spaceCount: 0 + wordCount: 1 + linkCount: 0 + lineCount: 1 + pageCount: 1 + materialCount: 1 + m_havePropertiesChanged: 1 + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_spriteAnimator: {fileID: 0} + m_isInputParsingRequired: 1 + m_inputSource: 0 + m_hasFontAssetChanged: 0 + m_subTextObjects: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!222 &222000010570603678 CanvasRenderer: m_ObjectHideFlags: 1 @@ -671,8 +942,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -0.25, y: 0} - m_SizeDelta: {x: -0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 200, y: 50} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000011444372664 RectTransform: @@ -768,8 +1039,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0.25, y: 0} - m_SizeDelta: {x: -0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224000013716393632 RectTransform: diff --git a/Tools/SelectionTool/Prefabs/SettingsUI.prefab.meta b/Tools/SelectionTool/Prefabs/SettingsUI.prefab.meta index 43f4ef9a4..baf065069 100644 --- a/Tools/SelectionTool/Prefabs/SettingsUI.prefab.meta +++ b/Tools/SelectionTool/Prefabs/SettingsUI.prefab.meta @@ -1,8 +1,10 @@ fileFormatVersion: 2 guid: 3f593adfd4b4c6745a99c1a237ba6902 -timeCreated: 1491439922 +timeCreated: 1512792311 licenseType: Pro NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Tools/SelectionTool/SelectionTool.cs b/Tools/SelectionTool/SelectionTool.cs index 88779434e..8b44c8890 100644 --- a/Tools/SelectionTool/SelectionTool.cs +++ b/Tools/SelectionTool/SelectionTool.cs @@ -1,614 +1,614 @@ -#if UNITY_EDITOR -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor.Experimental.EditorVR.Core; -using UnityEditor.Experimental.EditorVR.Proxies; -using UnityEditor.Experimental.EditorVR.UI; -using UnityEditor.Experimental.EditorVR.Utilities; -using UnityEngine; -using UnityEngine.InputNew; -using UnityEngine.UI; - -namespace UnityEditor.Experimental.EditorVR.Tools -{ - sealed class SelectionTool : MonoBehaviour, ITool, IUsesRayOrigin, IUsesRaycastResults, ICustomActionMap, - ISetHighlight, ISelectObject, ISetManipulatorsVisible, IIsHoveringOverUI, IUsesDirectSelection, ILinkedObject, - ICanGrabObject, IGetManipulatorDragState, IUsesNode, IGetRayVisibility, IIsMainMenuVisible, IIsInMiniWorld, - IRayToNode, IGetDefaultRayColor, ISetDefaultRayColor, ITooltip, ITooltipPlacement, ISetTooltipVisibility, - IUsesDeviceType, IMenuIcon, IUsesPointer, IRayVisibilitySettings, IUsesViewerScale, ICheckBounds, - ISettingsMenuItemProvider, ISerializePreferences, IStandardIgnoreList, IBlockUIInteraction, IRequestFeedback, - IGetVRPlayerObjects - { - [Serializable] - class Preferences - { - [SerializeField] - bool m_SphereMode; - - public bool sphereMode - { - get { return m_SphereMode; } - set { m_SphereMode = value; } - } - } - - const float k_MultiselectHueShift = 0.5f; - static readonly Vector3 k_TouchTooltipPosition = new Vector3(0, -0.08f, -0.13f); - static readonly Vector3 k_ViveTooltipPosition = new Vector3(0, 0.05f, -0.18f); - const float k_BLockSelectDragThreshold = 0.01f; - static readonly Quaternion k_TooltipRotation = Quaternion.AngleAxis(90, Vector3.right); - - [SerializeField] - Sprite m_Icon; - - [SerializeField] - ActionMap m_ActionMap; - - [SerializeField] - GameObject m_BlockSelectCube; - - [SerializeField] - GameObject m_BlockSelectSphere; - - [SerializeField] - GameObject m_SettingsMenuItemPrefab; - - Preferences m_Preferences; - - GameObject m_PressedObject; - - SelectionInput m_SelectionInput; - - float m_LastMultiSelectClickTime; - Color m_NormalRayColor; - Color m_MultiselectRayColor; - bool m_MultiSelect; - bool m_HasDirectHover; - bool m_BlockSelect; - Vector3 m_SelectStartPosition; - Renderer m_BlockSelectCubeRenderer; - - readonly BindingDictionary m_Controls = new BindingDictionary(); - readonly List m_SelectFeedback = new List(); - readonly List m_DirectSelectFeedback = new List(); - - Toggle m_CubeToggle; - Toggle m_SphereToggle; - bool m_BlockValueChangedListener; - - readonly Dictionary m_HoverGameObjects = new Dictionary(); - - readonly Dictionary m_SelectionHoverGameObjects = new Dictionary(); - readonly List m_BlockSelectHoverGameObjects = new List(); - - public ActionMap actionMap { get { return m_ActionMap; } } - public bool ignoreLocking { get { return false; } } - - public Transform rayOrigin { get; set; } - public Node node { private get; set; } - - public Sprite icon { get { return m_Icon; } } - - public event Action hovered; - - public List ignoreList { private get; set; } - public List linkedObjects { get; set; } - - public string tooltipText { get { return m_MultiSelect ? "Multi-Select Enabled" : ""; } } - public Transform tooltipTarget { get; private set; } - public Transform tooltipSource { get { return rayOrigin; } } - public TextAlignment tooltipAlignment { get { return TextAlignment.Center; } } - - public GameObject settingsMenuItemPrefab { get { return m_SettingsMenuItemPrefab; } } - - public GameObject settingsMenuItemInstance - { - set - { - var defaultToggleGroup = value.GetComponentInChildren(); - foreach (var toggle in value.GetComponentsInChildren()) - { - if (toggle == defaultToggleGroup.defaultToggle) - { - m_CubeToggle = toggle; - toggle.onValueChanged.AddListener(isOn => - { - if (m_BlockValueChangedListener) - return; - - // m_Preferences on all instances refer - m_Preferences.sphereMode = !isOn; - foreach (var linkedObject in linkedObjects) - { - var selectionTool = (SelectionTool)linkedObject; - if (selectionTool != this) - { - selectionTool.m_BlockValueChangedListener = true; - - //selectionTool.m_ToggleGroup.NotifyToggleOn(isOn ? m_CubeToggle : m_SphereToggle); - // HACK: Toggle Group claims these toggles are not a part of the group - selectionTool.m_CubeToggle.isOn = isOn; - selectionTool.m_SphereToggle.isOn = !isOn; - selectionTool.m_BlockValueChangedListener = false; - } - } - }); - } - else - { - m_SphereToggle = toggle; - } - } - } - } - - // Local method use only -- created here to reduce garbage collection - static readonly Dictionary k_TempHovers = new Dictionary(); - - void Start() - { - if (this.IsSharedUpdater(this) && m_Preferences == null) - { - m_Preferences = new Preferences(); - - // Share one preferences object across all instances - foreach (var linkedObject in linkedObjects) - { - ((SelectionTool)linkedObject).m_Preferences = m_Preferences; - } - } - - m_NormalRayColor = this.GetDefaultRayColor(rayOrigin); - m_MultiselectRayColor = m_NormalRayColor; - m_MultiselectRayColor = MaterialUtils.HueShift(m_MultiselectRayColor, k_MultiselectHueShift); - - tooltipTarget = ObjectUtils.CreateEmptyGameObject("SelectionTool Tooltip Target", rayOrigin).transform; - tooltipTarget.localPosition = this.GetDeviceType() == DeviceType.Oculus ? k_TouchTooltipPosition : k_ViveTooltipPosition; - tooltipTarget.localRotation = k_TooltipRotation; - - m_BlockSelectCube = ObjectUtils.Instantiate(m_BlockSelectCube, transform); - m_BlockSelectCube.SetActive(false); - m_BlockSelectCubeRenderer = m_BlockSelectCube.GetComponent(); - - m_BlockSelectSphere = ObjectUtils.Instantiate(m_BlockSelectSphere, transform); - m_BlockSelectSphere.SetActive(false); - - InputUtils.GetBindingDictionaryFromActionMap(m_ActionMap, m_Controls); - } - - void OnDestroy() - { - ObjectUtils.Destroy(m_BlockSelectCube); - this.ClearFeedbackRequests(); - } - - public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeControl) - { - if (this.GetManipulatorDragState()) - return; - - m_SelectionInput = (SelectionInput)input; - - var multiSelectControl = m_SelectionInput.multiSelect; - if (this.GetDeviceType() == DeviceType.Vive) - multiSelectControl = m_SelectionInput.multiSelectAlt; - - if (multiSelectControl.wasJustPressed) - { - var realTime = Time.realtimeSinceStartup; - if (UIUtils.IsDoubleClick(realTime - m_LastMultiSelectClickTime)) - { - foreach (var linkedObject in linkedObjects) - { - var selectionTool = (SelectionTool)linkedObject; - selectionTool.m_MultiSelect = !selectionTool.m_MultiSelect; - this.HideTooltip(selectionTool); - } - - if (m_MultiSelect) - this.ShowTooltip(this); - } - - m_LastMultiSelectClickTime = realTime; - } - - this.SetDefaultRayColor(rayOrigin, m_MultiSelect ? m_MultiselectRayColor : m_NormalRayColor); - - if (this.IsSharedUpdater(this)) - { - this.SetManipulatorsVisible(this, !m_MultiSelect); - - m_SelectionHoverGameObjects.Clear(); - foreach (var linkedObject in linkedObjects) - { - var selectionTool = (SelectionTool)linkedObject; - selectionTool.m_HasDirectHover = false; // Clear old hover state - - if (selectionTool.m_BlockSelect) - continue; - - if (!selectionTool.IsRayActive()) - continue; - - var selectionRayOrigin = selectionTool.rayOrigin; - - var hover = this.GetFirstGameObject(selectionRayOrigin); - - if (!selectionTool.GetSelectionCandidate(ref hover)) - continue; - - if (hover) - { - GameObject lastHover; - if (m_HoverGameObjects.TryGetValue(selectionRayOrigin, out lastHover) && lastHover != hover) - this.SetHighlight(lastHover, false, selectionRayOrigin); - - m_SelectionHoverGameObjects[selectionRayOrigin] = hover; - m_HoverGameObjects[selectionRayOrigin] = hover; - } - } - - var directSelection = this.GetDirectSelection(); - - // Unset highlight old hovers - k_TempHovers.Clear(); - foreach (var kvp in m_HoverGameObjects) - { - k_TempHovers[kvp.Key] = kvp.Value; - } - - foreach (var kvp in k_TempHovers) - { - var directRayOrigin = kvp.Key; - var hover = kvp.Value; - - if (!directSelection.ContainsKey(directRayOrigin) - && !m_SelectionHoverGameObjects.ContainsKey(directRayOrigin)) - { - this.SetHighlight(hover, false, directRayOrigin); - m_HoverGameObjects.Remove(directRayOrigin); - } - } - - // Find new hovers - foreach (var kvp in directSelection) - { - var directRayOrigin = kvp.Key; - var directHoveredObject = kvp.Value; - - var directSelectionCandidate = this.GetSelectionCandidate(directHoveredObject, true); - - // Can't select this object (it might be locked or static) - if (directHoveredObject && !directSelectionCandidate) - { - if (directHoveredObject != null) - this.SetHighlight(directHoveredObject, false); - - continue; - } - - if (directSelectionCandidate) - directHoveredObject = directSelectionCandidate; - - if (!this.CanGrabObject(directHoveredObject, directRayOrigin)) - continue; - - var grabbingNode = this.RequestNodeFromRayOrigin(directRayOrigin); - var selectionTool = linkedObjects.Cast().FirstOrDefault(linkedObject => linkedObject.node == grabbingNode); - if (selectionTool == null) - continue; - - if (selectionTool.m_BlockSelect) - continue; - - GameObject lastHover; - if (m_HoverGameObjects.TryGetValue(directRayOrigin, out lastHover) && lastHover != directHoveredObject) - this.SetHighlight(lastHover, false, directRayOrigin); - - if (!selectionTool.IsDirectActive()) - { - m_HoverGameObjects.Remove(directRayOrigin); - this.SetHighlight(directHoveredObject, false, directRayOrigin); - continue; - } - - // Only overwrite an existing selection if it does not contain the hovered object - // In the case of multi-select, only add, do not remove - if (selectionTool.m_SelectionInput.select.wasJustPressed && !Selection.objects.Contains(directHoveredObject)) - this.SelectObject(directHoveredObject, directRayOrigin, m_MultiSelect); - - m_HoverGameObjects[directRayOrigin] = directHoveredObject; - selectionTool.m_HasDirectHover = true; - } - - // Set highlight on new hovers - foreach (var hover in m_HoverGameObjects) - { - this.SetHighlight(hover.Value, true, hover.Key); - } - } - - if (!m_HasDirectHover) - HideDirectSelectFeedback(); - else if (m_DirectSelectFeedback.Count == 0) - ShowDirectSelectFeedback(); - - GameObject hoveredObject = null; - var rayActive = IsRayActive(); - if (rayActive) - { - // Need to call GetFirstGameObject a second time because we do not guarantee shared updater executes first - hoveredObject = this.GetFirstGameObject(rayOrigin); - - if (hovered != null) - hovered(hoveredObject, rayOrigin); - - GetSelectionCandidate(ref hoveredObject); - - if (hoveredObject && this.GetVRPlayerObjects().Contains(hoveredObject)) - hoveredObject = null; - } - - if (!hoveredObject) - HideSelectFeedback(); - else if (m_SelectFeedback.Count == 0) - ShowSelectFeedback(); - - var pointerPosition = this.GetPointerPosition(rayOrigin); - - // Capture object on press - var select = m_SelectionInput.select; - if (select.wasJustPressed) - { - m_SelectStartPosition = pointerPosition; - - // Ray selection only if ray is visible - m_PressedObject = hoveredObject; - } - - if (select.isHeld) - { - var startToEnd = pointerPosition - m_SelectStartPosition; - var visuals = m_Preferences.sphereMode ? m_BlockSelectSphere : m_BlockSelectCube; - var distance = startToEnd.magnitude; - if (!m_BlockSelect && distance > k_BLockSelectDragThreshold * this.GetViewerScale()) - { - m_BlockSelect = true; - visuals.SetActive(true); - - m_PressedObject = null; - this.AddRayVisibilitySettings(rayOrigin, this, false, true); - this.SetUIBlockedForRayOrigin(rayOrigin, true); - } - - if (m_BlockSelect) - this.SetManipulatorsVisible(this, false); - - //TODO: use hashsets to only unset highlights for removed objects - foreach (var hover in m_BlockSelectHoverGameObjects) - { - this.SetHighlight(hover, false, rayOrigin); - } - m_BlockSelectHoverGameObjects.Clear(); - - var visualsTransform = visuals.transform; - if (m_Preferences.sphereMode) - { - visualsTransform.localScale = Vector3.one * distance * 2; - visualsTransform.position = m_SelectStartPosition; - this.CheckSphere(m_SelectStartPosition, distance, m_BlockSelectHoverGameObjects, ignoreList); - } - else - { - visualsTransform.localScale = startToEnd; - visualsTransform.position = m_SelectStartPosition + startToEnd * 0.5f; - this.CheckBounds(m_BlockSelectCubeRenderer.bounds, m_BlockSelectHoverGameObjects, ignoreList); - } - - foreach (var hover in m_BlockSelectHoverGameObjects) - { - this.SetHighlight(hover, true, rayOrigin); - } - - if (m_BlockSelect) - consumeControl(select); - } - - // Make selection on release - if (select.wasJustReleased) - { - if (m_BlockSelect) - { - if (!m_MultiSelect) - { - this.SetManipulatorsVisible(this, true); - Selection.activeGameObject = null; - } - - this.SelectObjects(m_BlockSelectHoverGameObjects, rayOrigin, m_MultiSelect); - - foreach (var hover in m_BlockSelectHoverGameObjects) - { - if (hover != null) - this.SetHighlight(hover, false, rayOrigin); - } - - this.ResetDirectSelectionState(); - } - else if (rayActive) - { - if (m_PressedObject == hoveredObject) - { - this.SelectObject(m_PressedObject, rayOrigin, m_MultiSelect, true); - this.ResetDirectSelectionState(); - - if (m_PressedObject != null) - this.SetHighlight(m_PressedObject, false, rayOrigin); - } - - if (m_PressedObject) - consumeControl(select); - } - - this.SetUIBlockedForRayOrigin(rayOrigin, false); - this.RemoveRayVisibilitySettings(rayOrigin, this); - (m_Preferences.sphereMode ? m_BlockSelectSphere : m_BlockSelectCube).SetActive(false); - m_PressedObject = null; - m_BlockSelect = false; - } - } - - bool GetSelectionCandidate(ref GameObject hoveredObject) - { - var selectionCandidate = this.GetSelectionCandidate(hoveredObject, true); - - // Can't select this object (it might be locked or static) - if (hoveredObject && !selectionCandidate) - { - if (hoveredObject != null) - this.SetHighlight(hoveredObject, false); - - return false; - } - - if (selectionCandidate) - hoveredObject = selectionCandidate; - - return true; - } - - bool IsDirectActive() - { - if (rayOrigin == null) - return false; - - if (!this.IsConeVisible(rayOrigin)) - return false; - - if (this.IsInMiniWorld(rayOrigin)) - return true; - - if (this.IsMainMenuVisible(rayOrigin)) - return false; - - return true; - } - - bool IsRayActive() - { - if (rayOrigin == null) - return false; - - if (this.IsHoveringOverUI(rayOrigin)) - return false; - - if (this.IsMainMenuVisible(rayOrigin)) - return false; - - if (this.IsInMiniWorld(rayOrigin)) - return false; - - if (!this.IsRayVisible(rayOrigin)) - return false; - - return true; - } - - void OnDisable() - { - foreach (var kvp in m_HoverGameObjects) - { - this.SetHighlight(kvp.Value, false, kvp.Key); - } - m_HoverGameObjects.Clear(); - } - - public void OnResetDirectSelectionState() { } - - public object OnSerializePreferences() - { - if (this.IsSharedUpdater(this)) - { - // Share one preferences object across all instances - foreach (var linkedObject in linkedObjects) - { - ((SelectionTool)linkedObject).m_Preferences = m_Preferences; - } - - return m_Preferences; - } - - return null; - } - - public void OnDeserializePreferences(object obj) - { - if (this.IsSharedUpdater(this)) - { - var preferences = obj as Preferences; - if (preferences != null) - m_Preferences = preferences; - - // Share one preferences object across all instances - foreach (var linkedObject in linkedObjects) - { - ((SelectionTool)linkedObject).m_Preferences = m_Preferences; - } - - m_SphereToggle.isOn = m_Preferences.sphereMode; - m_CubeToggle.isOn = !m_Preferences.sphereMode; - } - } - - void ShowFeedback(List requests, string controlName, string tooltipText = null) - { - if (tooltipText == null) - tooltipText = controlName; - - List ids; - if (m_Controls.TryGetValue(controlName, out ids)) - { - foreach (var id in ids) - { - var request = (ProxyFeedbackRequest)this.GetFeedbackRequestObject(typeof(ProxyFeedbackRequest)); - request.node = node; - request.control = id; - request.tooltipText = tooltipText; - requests.Add(request); - this.AddFeedbackRequest(request); - } - } - } - - void ShowSelectFeedback() - { - ShowFeedback(m_SelectFeedback, "Select"); - } - - void ShowDirectSelectFeedback() - { - ShowFeedback(m_DirectSelectFeedback, "Select", "Direct Select"); - } - - void HideFeedback(List requests) - { - foreach (var request in requests) - { - this.RemoveFeedbackRequest(request); - } - requests.Clear(); - } - - void HideSelectFeedback() - { - HideFeedback(m_SelectFeedback); - } - - void HideDirectSelectFeedback() - { - HideFeedback(m_DirectSelectFeedback); - } - } -} -#endif +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor.Experimental.EditorVR.Core; +using UnityEditor.Experimental.EditorVR.Proxies; +using UnityEditor.Experimental.EditorVR.UI; +using UnityEditor.Experimental.EditorVR.Utilities; +using UnityEngine; +using UnityEngine.InputNew; +using UnityEngine.UI; + +namespace UnityEditor.Experimental.EditorVR.Tools +{ + sealed class SelectionTool : MonoBehaviour, ITool, IUsesRayOrigin, IUsesRaycastResults, ICustomActionMap, + ISetHighlight, ISelectObject, ISetManipulatorsVisible, IIsHoveringOverUI, IUsesDirectSelection, ILinkedObject, + ICanGrabObject, IGetManipulatorDragState, IUsesNode, IGetRayVisibility, IIsMainMenuVisible, IIsInMiniWorld, + IRayToNode, IGetDefaultRayColor, ISetDefaultRayColor, ITooltip, ITooltipPlacement, ISetTooltipVisibility, + IUsesDeviceType, IMenuIcon, IUsesPointer, IRayVisibilitySettings, IUsesViewerScale, ICheckBounds, + ISettingsMenuItemProvider, ISerializePreferences, IStandardIgnoreList, IBlockUIInteraction, IRequestFeedback, + IGetVRPlayerObjects + { + [Serializable] + class Preferences + { + [SerializeField] + bool m_SphereMode; + + public bool sphereMode + { + get { return m_SphereMode; } + set { m_SphereMode = value; } + } + } + + const float k_MultiselectHueShift = 0.5f; + static readonly Vector3 k_TouchTooltipPosition = new Vector3(0, -0.08f, -0.13f); + static readonly Vector3 k_ViveTooltipPosition = new Vector3(0, 0.05f, -0.18f); + const float k_BLockSelectDragThreshold = 0.01f; + static readonly Quaternion k_TooltipRotation = Quaternion.AngleAxis(90, Vector3.right); + + [SerializeField] + Sprite m_Icon; + + [SerializeField] + ActionMap m_ActionMap; + + [SerializeField] + GameObject m_BlockSelectCube; + + [SerializeField] + GameObject m_BlockSelectSphere; + + [SerializeField] + GameObject m_SettingsMenuItemPrefab; + + Preferences m_Preferences; + + GameObject m_PressedObject; + + SelectionInput m_SelectionInput; + + float m_LastMultiSelectClickTime; + Color m_NormalRayColor; + Color m_MultiselectRayColor; + bool m_MultiSelect; + bool m_HasDirectHover; + bool m_BlockSelect; + Vector3 m_SelectStartPosition; + Renderer m_BlockSelectCubeRenderer; + + readonly BindingDictionary m_Controls = new BindingDictionary(); + readonly List m_SelectFeedback = new List(); + readonly List m_DirectSelectFeedback = new List(); + + Toggle m_CubeToggle; + Toggle m_SphereToggle; + bool m_BlockValueChangedListener; + + readonly Dictionary m_HoverGameObjects = new Dictionary(); + + readonly Dictionary m_SelectionHoverGameObjects = new Dictionary(); + readonly List m_BlockSelectHoverGameObjects = new List(); + + public ActionMap actionMap { get { return m_ActionMap; } } + public bool ignoreLocking { get { return false; } } + + public Transform rayOrigin { get; set; } + public Node node { private get; set; } + + public Sprite icon { get { return m_Icon; } } + + public event Action hovered; + + public List ignoreList { private get; set; } + public List linkedObjects { get; set; } + + public string tooltipText { get { return m_MultiSelect ? "Multi-Select Enabled" : ""; } } + public Transform tooltipTarget { get; private set; } + public Transform tooltipSource { get { return rayOrigin; } } + public TextAlignment tooltipAlignment { get { return TextAlignment.Center; } } + + public GameObject settingsMenuItemPrefab { get { return m_SettingsMenuItemPrefab; } } + + public GameObject settingsMenuItemInstance + { + set + { + var defaultToggleGroup = value.GetComponentInChildren(); + foreach (var toggle in value.GetComponentsInChildren()) + { + if (toggle == defaultToggleGroup.defaultToggle) + { + m_CubeToggle = toggle; + toggle.onValueChanged.AddListener(isOn => + { + if (m_BlockValueChangedListener) + return; + + // m_Preferences on all instances refer + m_Preferences.sphereMode = !isOn; + foreach (var linkedObject in linkedObjects) + { + var selectionTool = (SelectionTool)linkedObject; + if (selectionTool != this) + { + selectionTool.m_BlockValueChangedListener = true; + + //selectionTool.m_ToggleGroup.NotifyToggleOn(isOn ? m_CubeToggle : m_SphereToggle); + // HACK: Toggle Group claims these toggles are not a part of the group + selectionTool.m_CubeToggle.isOn = isOn; + selectionTool.m_SphereToggle.isOn = !isOn; + selectionTool.m_BlockValueChangedListener = false; + } + } + }); + } + else + { + m_SphereToggle = toggle; + } + } + } + } + + // Local method use only -- created here to reduce garbage collection + static readonly Dictionary k_TempHovers = new Dictionary(); + + void Start() + { + if (this.IsSharedUpdater(this) && m_Preferences == null) + { + m_Preferences = new Preferences(); + + // Share one preferences object across all instances + foreach (var linkedObject in linkedObjects) + { + ((SelectionTool)linkedObject).m_Preferences = m_Preferences; + } + } + + m_NormalRayColor = this.GetDefaultRayColor(rayOrigin); + m_MultiselectRayColor = m_NormalRayColor; + m_MultiselectRayColor = MaterialUtils.HueShift(m_MultiselectRayColor, k_MultiselectHueShift); + + tooltipTarget = ObjectUtils.CreateEmptyGameObject("SelectionTool Tooltip Target", rayOrigin).transform; + tooltipTarget.localPosition = this.GetDeviceType() == DeviceType.Oculus ? k_TouchTooltipPosition : k_ViveTooltipPosition; + tooltipTarget.localRotation = k_TooltipRotation; + + m_BlockSelectCube = ObjectUtils.Instantiate(m_BlockSelectCube, transform); + m_BlockSelectCube.SetActive(false); + m_BlockSelectCubeRenderer = m_BlockSelectCube.GetComponent(); + + m_BlockSelectSphere = ObjectUtils.Instantiate(m_BlockSelectSphere, transform); + m_BlockSelectSphere.SetActive(false); + + InputUtils.GetBindingDictionaryFromActionMap(m_ActionMap, m_Controls); + } + + void OnDestroy() + { + ObjectUtils.Destroy(m_BlockSelectCube); + this.ClearFeedbackRequests(); + } + + public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeControl) + { + if (this.GetManipulatorDragState()) + return; + + m_SelectionInput = (SelectionInput)input; + + var multiSelectControl = m_SelectionInput.multiSelect; + if (this.GetDeviceType() == DeviceType.Vive) + multiSelectControl = m_SelectionInput.multiSelectAlt; + + if (multiSelectControl.wasJustPressed) + { + var realTime = Time.realtimeSinceStartup; + if (UIUtils.IsDoubleClick(realTime - m_LastMultiSelectClickTime)) + { + foreach (var linkedObject in linkedObjects) + { + var selectionTool = (SelectionTool)linkedObject; + selectionTool.m_MultiSelect = !selectionTool.m_MultiSelect; + this.HideTooltip(selectionTool); + } + + if (m_MultiSelect) + this.ShowTooltip(this); + } + + m_LastMultiSelectClickTime = realTime; + } + + this.SetDefaultRayColor(rayOrigin, m_MultiSelect ? m_MultiselectRayColor : m_NormalRayColor); + + if (this.IsSharedUpdater(this)) + { + this.SetManipulatorsVisible(this, !m_MultiSelect); + + m_SelectionHoverGameObjects.Clear(); + foreach (var linkedObject in linkedObjects) + { + var selectionTool = (SelectionTool)linkedObject; + selectionTool.m_HasDirectHover = false; // Clear old hover state + + if (selectionTool.m_BlockSelect) + continue; + + if (!selectionTool.IsRayActive()) + continue; + + var selectionRayOrigin = selectionTool.rayOrigin; + + var hover = this.GetFirstGameObject(selectionRayOrigin); + + if (!selectionTool.GetSelectionCandidate(ref hover)) + continue; + + if (hover) + { + GameObject lastHover; + if (m_HoverGameObjects.TryGetValue(selectionRayOrigin, out lastHover) && lastHover != hover) + this.SetHighlight(lastHover, false, selectionRayOrigin); + + m_SelectionHoverGameObjects[selectionRayOrigin] = hover; + m_HoverGameObjects[selectionRayOrigin] = hover; + } + } + + var directSelection = this.GetDirectSelection(); + + // Unset highlight old hovers + k_TempHovers.Clear(); + foreach (var kvp in m_HoverGameObjects) + { + k_TempHovers[kvp.Key] = kvp.Value; + } + + foreach (var kvp in k_TempHovers) + { + var directRayOrigin = kvp.Key; + var hover = kvp.Value; + + if (!directSelection.ContainsKey(directRayOrigin) + && !m_SelectionHoverGameObjects.ContainsKey(directRayOrigin)) + { + this.SetHighlight(hover, false, directRayOrigin); + m_HoverGameObjects.Remove(directRayOrigin); + } + } + + // Find new hovers + foreach (var kvp in directSelection) + { + var directRayOrigin = kvp.Key; + var directHoveredObject = kvp.Value; + + var directSelectionCandidate = this.GetSelectionCandidate(directHoveredObject, true); + + // Can't select this object (it might be locked or static) + if (directHoveredObject && !directSelectionCandidate) + { + if (directHoveredObject != null) + this.SetHighlight(directHoveredObject, false); + + continue; + } + + if (directSelectionCandidate) + directHoveredObject = directSelectionCandidate; + + if (!this.CanGrabObject(directHoveredObject, directRayOrigin)) + continue; + + var grabbingNode = this.RequestNodeFromRayOrigin(directRayOrigin); + var selectionTool = linkedObjects.Cast().FirstOrDefault(linkedObject => linkedObject.node == grabbingNode); + if (selectionTool == null) + continue; + + if (selectionTool.m_BlockSelect) + continue; + + GameObject lastHover; + if (m_HoverGameObjects.TryGetValue(directRayOrigin, out lastHover) && lastHover != directHoveredObject) + this.SetHighlight(lastHover, false, directRayOrigin); + + if (!selectionTool.IsDirectActive()) + { + m_HoverGameObjects.Remove(directRayOrigin); + this.SetHighlight(directHoveredObject, false, directRayOrigin); + continue; + } + + // Only overwrite an existing selection if it does not contain the hovered object + // In the case of multi-select, only add, do not remove + if (selectionTool.m_SelectionInput.select.wasJustPressed && !Selection.objects.Contains(directHoveredObject)) + this.SelectObject(directHoveredObject, directRayOrigin, m_MultiSelect); + + m_HoverGameObjects[directRayOrigin] = directHoveredObject; + selectionTool.m_HasDirectHover = true; + } + + // Set highlight on new hovers + foreach (var hover in m_HoverGameObjects) + { + this.SetHighlight(hover.Value, true, hover.Key); + } + } + + if (!m_HasDirectHover) + HideDirectSelectFeedback(); + else if (m_DirectSelectFeedback.Count == 0) + ShowDirectSelectFeedback(); + + GameObject hoveredObject = null; + var rayActive = IsRayActive(); + if (rayActive) + { + // Need to call GetFirstGameObject a second time because we do not guarantee shared updater executes first + hoveredObject = this.GetFirstGameObject(rayOrigin); + + if (hovered != null) + hovered(hoveredObject, rayOrigin); + + GetSelectionCandidate(ref hoveredObject); + + if (hoveredObject && this.GetVRPlayerObjects().Contains(hoveredObject)) + hoveredObject = null; + } + + if (!hoveredObject) + HideSelectFeedback(); + else if (m_SelectFeedback.Count == 0) + ShowSelectFeedback(); + + var pointerPosition = this.GetPointerPosition(rayOrigin); + + // Capture object on press + var select = m_SelectionInput.select; + if (select.wasJustPressed) + { + m_SelectStartPosition = pointerPosition; + + // Ray selection only if ray is visible + m_PressedObject = hoveredObject; + } + + if (select.isHeld) + { + var startToEnd = pointerPosition - m_SelectStartPosition; + var visuals = m_Preferences.sphereMode ? m_BlockSelectSphere : m_BlockSelectCube; + var distance = startToEnd.magnitude; + if (!m_BlockSelect && distance > k_BLockSelectDragThreshold * this.GetViewerScale()) + { + m_BlockSelect = true; + visuals.SetActive(true); + + m_PressedObject = null; + this.AddRayVisibilitySettings(rayOrigin, this, false, true); + this.SetUIBlockedForRayOrigin(rayOrigin, true); + } + + if (m_BlockSelect) + this.SetManipulatorsVisible(this, false); + + //TODO: use hashsets to only unset highlights for removed objects + foreach (var hover in m_BlockSelectHoverGameObjects) + { + this.SetHighlight(hover, false, rayOrigin); + } + m_BlockSelectHoverGameObjects.Clear(); + + var visualsTransform = visuals.transform; + if (m_Preferences.sphereMode) + { + visualsTransform.localScale = Vector3.one * distance * 2; + visualsTransform.position = m_SelectStartPosition; + this.CheckSphere(m_SelectStartPosition, distance, m_BlockSelectHoverGameObjects, ignoreList); + } + else + { + visualsTransform.localScale = startToEnd; + visualsTransform.position = m_SelectStartPosition + startToEnd * 0.5f; + this.CheckBounds(m_BlockSelectCubeRenderer.bounds, m_BlockSelectHoverGameObjects, ignoreList); + } + + foreach (var hover in m_BlockSelectHoverGameObjects) + { + this.SetHighlight(hover, true, rayOrigin); + } + + if (m_BlockSelect) + consumeControl(select); + } + + // Make selection on release + if (select.wasJustReleased) + { + if (m_BlockSelect) + { + if (!m_MultiSelect) + { + this.SetManipulatorsVisible(this, true); + Selection.activeGameObject = null; + } + + this.SelectObjects(m_BlockSelectHoverGameObjects, rayOrigin, m_MultiSelect); + + foreach (var hover in m_BlockSelectHoverGameObjects) + { + if (hover != null) + this.SetHighlight(hover, false, rayOrigin); + } + + this.ResetDirectSelectionState(); + } + else if (rayActive) + { + if (m_PressedObject == hoveredObject) + { + this.SelectObject(m_PressedObject, rayOrigin, m_MultiSelect, true); + this.ResetDirectSelectionState(); + + if (m_PressedObject != null) + this.SetHighlight(m_PressedObject, false, rayOrigin); + } + + if (m_PressedObject) + consumeControl(select); + } + + this.SetUIBlockedForRayOrigin(rayOrigin, false); + this.RemoveRayVisibilitySettings(rayOrigin, this); + (m_Preferences.sphereMode ? m_BlockSelectSphere : m_BlockSelectCube).SetActive(false); + m_PressedObject = null; + m_BlockSelect = false; + } + } + + bool GetSelectionCandidate(ref GameObject hoveredObject) + { + var selectionCandidate = this.GetSelectionCandidate(hoveredObject, true); + + // Can't select this object (it might be locked or static) + if (hoveredObject && !selectionCandidate) + { + if (hoveredObject != null) + this.SetHighlight(hoveredObject, false); + + return false; + } + + if (selectionCandidate) + hoveredObject = selectionCandidate; + + return true; + } + + bool IsDirectActive() + { + if (rayOrigin == null) + return false; + + if (!this.IsConeVisible(rayOrigin)) + return false; + + if (this.IsInMiniWorld(rayOrigin)) + return true; + + if (this.IsMainMenuVisible(rayOrigin)) + return false; + + return true; + } + + bool IsRayActive() + { + if (rayOrigin == null) + return false; + + if (this.IsHoveringOverUI(rayOrigin)) + return false; + + if (this.IsMainMenuVisible(rayOrigin)) + return false; + + if (this.IsInMiniWorld(rayOrigin)) + return false; + + if (!this.IsRayVisible(rayOrigin)) + return false; + + return true; + } + + void OnDisable() + { + foreach (var kvp in m_HoverGameObjects) + { + this.SetHighlight(kvp.Value, false, kvp.Key); + } + m_HoverGameObjects.Clear(); + } + + public void OnResetDirectSelectionState() { } + + public object OnSerializePreferences() + { + if (this.IsSharedUpdater(this)) + { + // Share one preferences object across all instances + foreach (var linkedObject in linkedObjects) + { + ((SelectionTool)linkedObject).m_Preferences = m_Preferences; + } + + return m_Preferences; + } + + return null; + } + + public void OnDeserializePreferences(object obj) + { + if (this.IsSharedUpdater(this)) + { + var preferences = obj as Preferences; + if (preferences != null) + m_Preferences = preferences; + + // Share one preferences object across all instances + foreach (var linkedObject in linkedObjects) + { + ((SelectionTool)linkedObject).m_Preferences = m_Preferences; + } + + m_SphereToggle.isOn = m_Preferences.sphereMode; + m_CubeToggle.isOn = !m_Preferences.sphereMode; + } + } + + void ShowFeedback(List requests, string controlName, string tooltipText = null) + { + if (tooltipText == null) + tooltipText = controlName; + + List ids; + if (m_Controls.TryGetValue(controlName, out ids)) + { + foreach (var id in ids) + { + var request = (ProxyFeedbackRequest)this.GetFeedbackRequestObject(typeof(ProxyFeedbackRequest)); + request.node = node; + request.control = id; + request.tooltipText = tooltipText; + requests.Add(request); + this.AddFeedbackRequest(request); + } + } + } + + void ShowSelectFeedback() + { + ShowFeedback(m_SelectFeedback, "Select"); + } + + void ShowDirectSelectFeedback() + { + ShowFeedback(m_DirectSelectFeedback, "Select", "Direct Select"); + } + + void HideFeedback(List requests) + { + foreach (var request in requests) + { + this.RemoveFeedbackRequest(request); + } + requests.Clear(); + } + + void HideSelectFeedback() + { + HideFeedback(m_SelectFeedback); + } + + void HideDirectSelectFeedback() + { + HideFeedback(m_DirectSelectFeedback); + } + } +} +#endif diff --git a/Tools/TransformTool/TransformTool.cs b/Tools/TransformTool/TransformTool.cs index f88fce69f..9ab3a9e8d 100644 --- a/Tools/TransformTool/TransformTool.cs +++ b/Tools/TransformTool/TransformTool.cs @@ -58,7 +58,7 @@ public void Reset() } } - public void UpdatePositions(IUsesSnapping usesSnapping) + public void UpdatePositions(IUsesSnapping usesSnapping, bool interpolate = true) { if (suspended) return; @@ -75,9 +75,17 @@ public void UpdatePositions(IUsesSnapping usesSnapping) if (usesSnapping.DirectSnap(rayOrigin, grabbedObject, ref position, ref rotation, targetPosition, targetRotation)) { - var deltaTime = Time.deltaTime; - grabbedObject.position = Vector3.Lerp(grabbedObject.position, position, k_DirectLazyFollowTranslate * deltaTime); - grabbedObject.rotation = Quaternion.Lerp(grabbedObject.rotation, rotation, k_DirectLazyFollowRotate * deltaTime); + if (interpolate) + { + var deltaTime = Time.deltaTime; + grabbedObject.position = Vector3.Lerp(grabbedObject.position, position, k_DirectLazyFollowTranslate * deltaTime); + grabbedObject.rotation = Quaternion.Lerp(grabbedObject.rotation, rotation, k_DirectLazyFollowRotate * deltaTime); + } + else + { + grabbedObject.position = position; + grabbedObject.rotation = rotation; + } } else { @@ -595,7 +603,10 @@ public void Resume(Node node) { var grabData = GrabDataForNode(node); if (grabData != null) + { grabData.suspended = false; + grabData.UpdatePositions(this, false); + } } public Transform[] GetHeldObjects(Node node) @@ -616,7 +627,7 @@ public Transform[] GetHeldObjects(Node node) grabData.TransferTo(destRayOrigin, deltaOffset); this.ClearSnappingState(rayOrigin); - grabData.UpdatePositions(this); + grabData.UpdatePositions(this, false); // Prevent lock from getting stuck this.RemoveRayVisibilitySettings(rayOrigin, this); @@ -635,7 +646,7 @@ public void DropHeldObjects(Node node) var grabbedObjects = grabData.grabbedObjects; var rayOrigin = grabData.rayOrigin; - if (objectsDropped != null && !m_Scaling) + if (objectsDropped != null) objectsDropped(rayOrigin, grabbedObjects); if (node == Node.LeftHand) diff --git a/Tools/VacuumTool/VacuumTool.cs b/Tools/VacuumTool/VacuumTool.cs index bf6ec2bb0..5a83805f0 100644 --- a/Tools/VacuumTool/VacuumTool.cs +++ b/Tools/VacuumTool/VacuumTool.cs @@ -59,6 +59,8 @@ public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeCon var realTime = Time.realtimeSinceStartup; if (UIUtils.IsDoubleClick(realTime - m_LastClickTime)) { + consumeControl(vacuumInput.vacuum); + Coroutine coroutine; if (m_VacuumingCoroutines.TryGetValue(vacuumableTransform, out coroutine)) StopCoroutine(coroutine); diff --git a/UndoPatch.meta b/UndoPatch.meta new file mode 100644 index 000000000..8a73ddc27 --- /dev/null +++ b/UndoPatch.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 09bef22b7a38b1748826705905670959 +folderAsset: yes +timeCreated: 1512465425 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UndoPatch/UnityEngine.CoreModule_2017.2.0p1.zip b/UndoPatch/UnityEngine.CoreModule_2017.2.0p1.zip new file mode 100644 index 000000000..c9a2dbe90 --- /dev/null +++ b/UndoPatch/UnityEngine.CoreModule_2017.2.0p1.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:263509d40ec2fe536344bfaf6e74c421d384466634e67e6b46039f96931a5834 +size 248879 diff --git a/UndoPatch/UnityEngine.CoreModule_2017.2.0p1.zip.meta b/UndoPatch/UnityEngine.CoreModule_2017.2.0p1.zip.meta new file mode 100644 index 000000000..d53a7177e --- /dev/null +++ b/UndoPatch/UnityEngine.CoreModule_2017.2.0p1.zip.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 91ff1c9c19344e04b814821f72db55a8 +timeCreated: 1512465425 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Workspaces/Common/Scripts/FilterUI.cs b/Workspaces/Common/Scripts/FilterUI.cs index 4094de725..25b4b1546 100644 --- a/Workspaces/Common/Scripts/FilterUI.cs +++ b/Workspaces/Common/Scripts/FilterUI.cs @@ -189,7 +189,6 @@ void OnFilterClick(FilterButtonUI clickedButton) switch (clickedButton.text.text) { case k_AllText: - m_SummaryText.text = clickedButton.text.text; m_DescriptionText.text = "All objects are visible"; break; diff --git a/Workspaces/HierarchyWorkspace/Scripts/HierarchyListItem.cs b/Workspaces/HierarchyWorkspace/Scripts/HierarchyListItem.cs index 4b02ad769..22dbbf42d 100644 --- a/Workspaces/HierarchyWorkspace/Scripts/HierarchyListItem.cs +++ b/Workspaces/HierarchyWorkspace/Scripts/HierarchyListItem.cs @@ -509,8 +509,11 @@ void ReceiveDrop(BaseHandle handle, object dropObject) { var index = data.index; var gameObject = data.gameObject; + Transform transform = null; + if (gameObject != null) // In case we are dropping into the scene root + transform = gameObject.transform; + var dropGameObject = dropData.gameObject; - var transform = gameObject.transform; var dropTransform = dropGameObject.transform; // OnHierarchyChanged doesn't happen until next frame--delay removal of the extra space diff --git a/Workspaces/PolyWorkspace/PolyWorkspace.cs b/Workspaces/PolyWorkspace/PolyWorkspace.cs index 2474708c5..8ac2c317d 100644 --- a/Workspaces/PolyWorkspace/PolyWorkspace.cs +++ b/Workspaces/PolyWorkspace/PolyWorkspace.cs @@ -25,9 +25,6 @@ namespace UnityEditor.Experimental.EditorVR.Workspaces [MainMenuItem("Poly", "Workspaces", "Import models from Google Poly")] sealed class PolyWorkspace : Workspace, ISerializeWorkspace { - const float k_XBounds = 1.094f; - const float k_YBounds = 0.2f; - const float k_MinScale = 0.05f; const float k_MaxScale = 0.2f; @@ -44,6 +41,10 @@ sealed class PolyWorkspace : Workspace, ISerializeWorkspace const string k_Medium = "Medium"; const string k_Simple = "Simple"; + static readonly Vector3 k_MinBounds = new Vector3(1.094f, 0.2f, 0.5f); + static readonly Vector3 k_ScrollHandleScale = new Vector3(1.03f, 0.02f, 1.02f); // Extra space for scrolling + static readonly Vector3 k_ScrollHandlePosition = new Vector3(0f, -0.015f, 0f); // Offset from content for collision purposes + [Serializable] class Preferences { @@ -89,7 +90,7 @@ public List assetData public override void Setup() { // Initial bounds must be set before the base.Setup() is called - minBounds = new Vector3(k_XBounds, k_YBounds, 0.5f); + minBounds = k_MinBounds; m_CustomStartingBounds = minBounds; base.Setup(); @@ -124,8 +125,8 @@ public override void Setup() var scrollHandle = m_PolyUI.scrollHandle; var scrollHandleTransform = scrollHandle.transform; scrollHandleTransform.SetParent(m_WorkspaceUI.topFaceContainer); - scrollHandleTransform.localScale = new Vector3(1.03f, 0.02f, 1.02f); // Extra space for scrolling - scrollHandleTransform.localPosition = new Vector3(0f, -0.015f, 0f); // Offset from content for collision purposes + scrollHandleTransform.localScale = k_ScrollHandleScale; + scrollHandleTransform.localPosition = k_ScrollHandlePosition; scrollHandle.dragStarted += OnScrollDragStarted; scrollHandle.dragging += OnScrollDragging; diff --git a/Workspaces/PolyWorkspace/Scripts/PolyGridAsset.cs b/Workspaces/PolyWorkspace/Scripts/PolyGridAsset.cs index 544071c02..009fbb67a 100644 --- a/Workspaces/PolyWorkspace/Scripts/PolyGridAsset.cs +++ b/Workspaces/PolyWorkspace/Scripts/PolyGridAsset.cs @@ -36,7 +36,7 @@ public class PolyGridAsset : ListViewItemData, IWeb public Texture2D thumbnail { get { return m_Thumbnail; } } public bool initialized { get { return m_Initialized; } } public long complexity { get { return m_Complexity; } } - public override string index { get { return m_Asset.name; } } + public override string index { get { return m_Asset.name; } } // PolyAsset.name is the GUID public event Action modelImportCompleted; public event Action thumbnailImportCompleted; diff --git a/Workspaces/PolyWorkspace/Scripts/PolyGridItem.cs b/Workspaces/PolyWorkspace/Scripts/PolyGridItem.cs index 9f93d2628..553ee3a78 100644 --- a/Workspaces/PolyWorkspace/Scripts/PolyGridItem.cs +++ b/Workspaces/PolyWorkspace/Scripts/PolyGridItem.cs @@ -94,7 +94,6 @@ class PolyGridItem : DraggableListItem, IPlaceSceneObject Action m_CompleteHoverTransition; Action m_SetThumbnailScale; Action m_SetImportingScale; - Action m_SetImportingColor; void Awake() @@ -102,7 +101,6 @@ void Awake() m_CompleteHoverTransition = CompleteHoverTransition; m_SetThumbnailScale = SetThumbnailScale; m_SetImportingScale = SetImportingScale; - m_SetImportingColor = SetImportingColor; } @@ -422,7 +420,8 @@ IEnumerator AnimateVisibility(bool visible, Action callback) while (currentTime < k_TransitionDuration) { currentTime += Time.deltaTime; - transform.localScale = Vector3.Lerp(currentScale, targetScale, currentTime / k_TransitionDuration); + transform.localScale = Vector3.Lerp(currentScale, targetScale, + MathUtilsExt.SmoothInOutLerpFloat(currentTime / k_TransitionDuration)); yield return null; } @@ -446,8 +445,7 @@ IEnumerator ShowGrabbedObject() currentPreviewOffset = m_PreviewObjectClone.localPosition; var currentTime = 0f; - var currentVelocity = 0f; - const float kDuration = 1f; + const float duration = 1f; var targetScale = Vector3.one * k_IconPreviewScale; var pivotOffset = Vector3.zero; @@ -484,13 +482,14 @@ IEnumerator ShowGrabbedObject() } } - while (currentTime < kDuration - 0.05f) + while (currentTime < duration) { if (m_DragObject == null) yield break; // Exit coroutine if m_GrabbedObject is destroyed before the loop is finished - currentTime = MathUtilsExt.SmoothDamp(currentTime, kDuration, ref currentVelocity, 0.5f, Mathf.Infinity, Time.deltaTime); - m_DragObject.localScale = Vector3.Lerp(currentLocalScale, targetScale, currentTime); + currentTime += Time.deltaTime; + m_DragObject.localScale = Vector3.Lerp(currentLocalScale, targetScale, + MathUtilsExt.SmoothInOutLerpFloat(currentTime / duration)); if (m_PreviewObjectClone) { @@ -502,6 +501,7 @@ IEnumerator ShowGrabbedObject() } m_DragObject.localScale = targetScale; + //No need to hard-set the preview object position/rotation because they will set in OnDragging in parent class } static IEnumerator HideGrabbedObject(GameObject itemToHide) diff --git a/Workspaces/ProjectWorkspace/ProjectWorkspace.cs b/Workspaces/ProjectWorkspace/ProjectWorkspace.cs index 9a6ca57b6..67b736162 100644 --- a/Workspaces/ProjectWorkspace/ProjectWorkspace.cs +++ b/Workspaces/ProjectWorkspace/ProjectWorkspace.cs @@ -19,6 +19,9 @@ sealed class ProjectWorkspace : Workspace, IUsesProjectFolderData, IFilterUI, IS const float k_MinScale = 0.04f; const float k_MaxScale = 0.09f; + static readonly Vector3 k_MinBounds = new Vector3(MinBounds.x, k_YBounds, 0.5f); + static readonly Vector3 k_CustomStartingBounds = new Vector3(0.8f, k_YBounds, 0.5f); + bool m_AssetGridDragging; bool m_FolderPanelDragging; @@ -95,8 +98,8 @@ public List expandedFolders public override void Setup() { // Initial bounds must be set before the base.Setup() is called - minBounds = new Vector3(MinBounds.x, k_YBounds, 0.5f); - m_CustomStartingBounds = new Vector3(0.8f, k_YBounds, 0.5f); + minBounds = k_MinBounds; + m_CustomStartingBounds = k_CustomStartingBounds; base.Setup(); diff --git a/Workspaces/ProjectWorkspace/Scripts/AssetGridItem.cs b/Workspaces/ProjectWorkspace/Scripts/AssetGridItem.cs index 75ddfe76f..8047286fd 100644 --- a/Workspaces/ProjectWorkspace/Scripts/AssetGridItem.cs +++ b/Workspaces/ProjectWorkspace/Scripts/AssetGridItem.cs @@ -351,9 +351,11 @@ protected override void OnDragEnded(BaseHandle handle, HandleEventData eventData if (!this.IsOverShoulder(eventData.rayOrigin)) { - if (gridItem.m_PreviewObjectTransform) + var previewObjectTransform = gridItem.m_PreviewObjectTransform; + if (previewObjectTransform) { - this.PlaceSceneObject(gridItem.m_PreviewObjectTransform, m_PreviewPrefabScale); + Undo.RegisterCreatedObjectUndo(previewObjectTransform.gameObject, "Place Scene Object"); + this.PlaceSceneObject(previewObjectTransform, m_PreviewPrefabScale); } else { @@ -371,6 +373,7 @@ protected override void OnDragEnded(BaseHandle handle, HandleEventData eventData #endif this.AddToSpatialHash(go); + Undo.RegisterCreatedObjectUndo(go, "Project Workspace"); break; } } diff --git a/Workspaces/ProjectWorkspace/Shaders/StandardDecal.shader b/Workspaces/ProjectWorkspace/Shaders/StandardDecal.shader index 205517310..6197cbb44 100644 --- a/Workspaces/ProjectWorkspace/Shaders/StandardDecal.shader +++ b/Workspaces/ProjectWorkspace/Shaders/StandardDecal.shader @@ -32,14 +32,9 @@ Shader "EditorVR/Standard Decal" void surf (Input IN, inout SurfaceOutputStandard o) { - if (IN.uv_MainTex.x > 1 || IN.uv_MainTex.x < 0 - || IN.uv_MainTex.y > 1 || IN.uv_MainTex.y < 0) - o.Emission = 0; - else { - fixed4 c = tex2D(_MainTex, IN.uv_MainTex); - c *= _Color * c.a; - o.Emission = c.rgb; - } + fixed4 c = tex2D(_MainTex, IN.uv_MainTex); + c *= _Color * c.a; + o.Emission = c.rgb; } ENDCG }