void OnProxyActiveChanged(IProxy proxy) { proxy.hidden = !proxy.active; if (proxy.active) { var deviceData = m_ToolModule.deviceData; if (!deviceData.Any(dd => dd.proxy == proxy)) { var moduleLoaderCore = ModuleLoaderCore.instance; var keyboardModule = moduleLoaderCore.GetModule <KeyboardModule>(); var highlightModule = moduleLoaderCore.GetModule <HighlightModule>(); foreach (var rayOriginPair in proxy.rayOrigins) { var node = rayOriginPair.Key; var rayOrigin = rayOriginPair.Value; var systemDevices = m_DeviceInputModule.GetSystemDevices(); for (int j = 0; j < systemDevices.Count; j++) { var device = systemDevices[j]; // Find device tagged with the node that matches this RayOrigin node var deviceNode = m_DeviceInputModule.GetDeviceNode(device); if (deviceNode == node) { var newDeviceData = new DeviceData(); deviceData.Add(newDeviceData); newDeviceData.proxy = proxy; newDeviceData.node = node; newDeviceData.rayOrigin = rayOrigin; newDeviceData.inputDevice = device; if (!this.HasProvider <IProvidesAddRaycastSource>()) { continue; } // Add RayOrigin transform, proxy and ActionMapInput references to input module list of sources this.AddRaycastSource(proxy, node, rayOrigin, source => { // Do not invalidate UI raycasts in the middle of a drag operation var eventData = source.eventData; if (!eventData.pointerDrag) { var sourceRayOrigin = source.rayOrigin; if (m_DirectSelectionModule != null && m_DirectSelectionModule.IsHovering(sourceRayOrigin)) { return(false); } var currentRaycast = eventData.pointerCurrentRaycast; var hoveredObject = currentRaycast.gameObject; // The manipulator needs rays to go through scene objects in order to work var isManipulator = hoveredObject && hoveredObject.GetComponentInParent <IManipulator>() != null; float sceneObjectDistance; var raycastObject = m_IntersectionModule.GetFirstGameObject(sourceRayOrigin, out sceneObjectDistance); var uiDistance = currentRaycast.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 && !ignoreList.Contains(raycastObject)) { return(false); } } if (m_MenuModule != null && !m_MenuModule.IsValidHover(source)) { return(false); } // Proceed only for raycast sources that haven't been blocked via IBlockUIInteraction if (source.blocked) { return(false); } return(true); }); } } rayOrigin.name = string.Format("{0} Ray Origin", node); var rayTransform = EditorXRUtils.Instantiate(m_ProxyRayPrefab.gameObject, rayOrigin, false).transform; rayTransform.position = rayOrigin.position; rayTransform.rotation = rayOrigin.rotation; var dpr = rayTransform.GetComponent <DefaultProxyRay>(); this.InjectFunctionalitySingle(dpr); m_DefaultRays.Add(rayOrigin, dpr); if (highlightModule != null) { dpr.SetColor(highlightModule.highlightColor); highlightModule.AddRayOriginForNode(node, rayOrigin); } if (keyboardModule != null) { keyboardModule.SpawnKeyboardMallet(rayOrigin); } var proxyExtras = m_ProxyExtras; if (proxyExtras) { var extraData = proxyExtras.data; List <GameObject> prefabs; if (extraData.TryGetValue(rayOriginPair.Key, out prefabs)) { foreach (var prefab in prefabs) { var go = this.InstantiateUI(prefab); go.transform.SetParent(rayOriginPair.Value, false); } } } var tester = rayOriginPair.Value.GetComponentInChildren <IntersectionTester>(); tester.active = proxy.active; m_IntersectionModule.AddTester(tester); if (m_WorkspaceModule != null) { switch (node) { case Node.LeftHand: m_WorkspaceModule.leftRayOrigin = rayOrigin; break; case Node.RightHand: m_WorkspaceModule.rightRayOrigin = rayOrigin; break; } } } if (m_ToolModule != null) { m_ToolModule.SpawnDefaultTools(proxy); } if (m_SerializedPreferences != null) { m_SerializedPreferences.DeserializePreferences(); } if (m_WorkspaceModule != null) { m_WorkspaceModule.CreateSerializedWorkspaces(); } } } }
void DespawnTool(DeviceData device, ITool tool) { var toolType = tool.GetType(); if (!IsDefaultTool(toolType)) { // Remove the tool if it is the current tool on this device tool stack if (device.currentTool == tool) { var topTool = device.toolData.Peek(); if (topTool == null || topTool.tool != device.currentTool) { Debug.LogError("Tool at top of stack is not current tool."); return; } if (device.customMenu != null) { device.menuHideData.Remove(device.customMenu); device.customMenu = null; } var oldTool = device.toolData.Pop(); oldTool.input.active = false; topTool = device.toolData.Peek(); device.currentTool = topTool.tool; // Pop this tool off any other stack that references it (for single instance tools) foreach (var otherDeviceData in deviceData) { if (otherDeviceData != device) { // 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) { otherDeviceData.toolsMenu.deleteToolsMenuButton(toolType, typeof(SelectionTool)); 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); UnityObjectUtils.Destroy((MonoBehaviour)otherTool); } } } // 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, device.rayOrigin); // Exclusive tools disable other tools underneath, so restore those if (tool is IExclusiveMode) { SetToolsEnabled(device, true); } UnityObjectUtils.Destroy((MonoBehaviour)tool); } }
internal bool IsValidHover(IRaycastSource source) { var eventData = source.eventData; var currentRaycast = eventData.pointerCurrentRaycast; var go = eventData.pointerDrag; if (!go) { go = currentRaycast.gameObject; } if (!go) { return(true); } if (go == gameObject) { return(true); } var rayOrigin = eventData.rayOrigin; DeviceData deviceData = null; foreach (var currentDevice in m_ToolModule.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 = currentRaycast.distance / this.GetViewerScale(); var menuHideFlags = deviceData.menuHideData; var mainMenu = deviceData.mainMenu; IMenu openMenu = mainMenu; if (deviceData.customMenu != null && menuHideFlags[mainMenu].hideFlags != 0) { openMenu = deviceData.customMenu; } if (openMenu == null) { return(false); } 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); }