/// <summary> /// Gets the currently active gesture, according to the mouse configuration and mouse button that is down. /// </summary> private ArticulatedHandPose.GestureId SelectGesture() { // Each check needs to verify that both: // 1) The corresponding mouse button is down (meaning the gesture, if defined, should be used) // 2) The gesture is defined. // If only #1 is checked and #2 is not checked, it's possible to "miss" transitions in cases where the user has // the left mouse button down and then while it is down, presses the right button, and then lifts the left. // It's not until both mouse buttons lift in that case, that the state finally "rests" to the DefaultHandGesture. if (KeyInputSystem.GetKey(profile.InteractionButton) && profile.LeftMouseHandGesture != ArticulatedHandPose.GestureId.None) { return(profile.LeftMouseHandGesture); } else if (KeyInputSystem.GetKey(profile.MouseLookButton) && profile.RightMouseHandGesture != ArticulatedHandPose.GestureId.None) { return(profile.RightMouseHandGesture); } else if (KeyInputSystem.GetKey(KeyBinding.FromMouseButton(KeyBinding.MouseButton.Middle)) && profile.MiddleMouseHandGesture != ArticulatedHandPose.GestureId.None) { return(profile.MiddleMouseHandGesture); } else { return(profile.DefaultHandGesture); } }
/// <summary> /// Update controller state based on keyboard and mouse input /// </summary> protected virtual void SimulateUserInput(MouseDelta mouseDelta) { float time = Time.time; if (KeyInputSystem.GetKeyDown(profile.ToggleLeftControllerKey)) { IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft; } if (KeyInputSystem.GetKeyDown(profile.ToggleRightControllerKey)) { IsAlwaysVisibleRight = !IsAlwaysVisibleRight; } if (!Application.isFocused && !KeyInputSystem.SimulatingInput) { IsSimulatingLeft = false; IsSimulatingRight = false; } else { if (KeyInputSystem.GetKeyDown(profile.LeftControllerManipulationKey)) { IsSimulatingLeft = true; if (lastSimulationLeft > 0.0f && time - lastSimulationLeft <= profile.DoublePressTime) { IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft; } lastSimulationLeft = time; } if (KeyInputSystem.GetKeyUp(profile.LeftControllerManipulationKey)) { IsSimulatingLeft = false; } if (KeyInputSystem.GetKeyDown(profile.RightControllerManipulationKey)) { IsSimulatingRight = true; if (lastSimulationRight > 0.0f && time - lastSimulationRight <= profile.DoublePressTime) { IsAlwaysVisibleRight = !IsAlwaysVisibleRight; } lastSimulationRight = time; } if (KeyInputSystem.GetKeyUp(profile.RightControllerManipulationKey)) { IsSimulatingRight = false; } if (isSimulatingGaze) { lastSimulationGaze = time; } } mouseRotation.Update(profile.ControllerRotateButton, cancelRotationKey, false); SimulateInput(ref lastInputTrackedTimestampLeft, InputStateLeft, IsSimulatingLeft, IsAlwaysVisibleLeft, mouseDelta, mouseRotation.IsRotating); SimulateInput(ref lastInputTrackedTimestampRight, InputStateRight, IsSimulatingRight, IsAlwaysVisibleRight, mouseDelta, mouseRotation.IsRotating); SimulateInput(ref lastInputTrackedTimestampGaze, InputStateGaze, isSimulatingGaze, false, mouseDelta, mouseRotation.IsRotating); }
/// <summary> /// Update hand state based on keyboard and mouse input /// </summary> private void SimulateUserInput(MouseDelta mouseDelta) { float time = Time.time; if (KeyInputSystem.GetKeyDown(profile.ToggleLeftHandKey)) { IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft; } if (KeyInputSystem.GetKeyDown(profile.ToggleRightHandKey)) { IsAlwaysVisibleRight = !IsAlwaysVisibleRight; } if (!Application.isFocused) { isSimulatingLeft = false; isSimulatingRight = false; } else { if (KeyInputSystem.GetKeyDown(profile.LeftHandManipulationKey)) { isSimulatingLeft = true; if (lastSimulationLeft > 0.0f && time - lastSimulationLeft <= profile.DoublePressTime) { IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft; } lastSimulationLeft = time; } if (KeyInputSystem.GetKeyUp(profile.LeftHandManipulationKey)) { isSimulatingLeft = false; } if (KeyInputSystem.GetKeyDown(profile.RightHandManipulationKey)) { isSimulatingRight = true; if (lastSimulationRight > 0.0f && time - lastSimulationRight <= profile.DoublePressTime) { IsAlwaysVisibleRight = !IsAlwaysVisibleRight; } lastSimulationRight = time; } if (KeyInputSystem.GetKeyUp(profile.RightHandManipulationKey)) { isSimulatingRight = false; } } mouseRotation.Update(profile.HandRotateButton, cancelRotationKey, false); SimulateHandInput(ref lastHandTrackedTimestampLeft, HandStateLeft, isSimulatingLeft, IsAlwaysVisibleLeft, mouseDelta, mouseRotation.IsRotating); SimulateHandInput(ref lastHandTrackedTimestampRight, HandStateRight, isSimulatingRight, IsAlwaysVisibleRight, mouseDelta, mouseRotation.IsRotating); float gestureAnimDelta = profile.HandGestureAnimationSpeed * Time.deltaTime; HandStateLeft.GestureBlending += gestureAnimDelta; HandStateRight.GestureBlending += gestureAnimDelta; }
/// <inheritdoc /> internal override void SimulateInput(ref long lastMotionControllerTrackedTimestamp, SimulatedControllerState state, bool isSimulating, bool isAlwaysVisible, MouseDelta mouseDelta, bool useMouseRotation) { var motionControllerState = state as SimulatedMotionControllerState; if (motionControllerState == null) { return; } bool enableTracking = isAlwaysVisible || isSimulating; if (!motionControllerState.IsTracked && enableTracking) { ResetInput(motionControllerState, isSimulating); } if (isSimulating) { motionControllerState.SimulateInput(mouseDelta, useMouseRotation, profile.MouseRotationSensitivity, profile.MouseControllerRotationSpeed, profile.ControllerJitterAmount); motionControllerState.ButtonState = new SimulatedMotionControllerButtonState { IsSelecting = KeyInputSystem.GetKey(profile.MotionControllerTriggerKey), IsGrabbing = KeyInputSystem.GetKey(profile.MotionControllerGrabKey), IsPressingMenu = KeyInputSystem.GetKey(profile.MotionControllerMenuKey) }; } // Update tracked state of a motion controller. // If hideTimeout value is null, motion controllers will stay visible after tracking stops. // TODO: DateTime.UtcNow can be quite imprecise, better use Stopwatch.GetTimestamp // https://stackoverflow.com/questions/2143140/c-sharp-datetime-now-precision DateTime currentTime = DateTime.UtcNow; if (enableTracking) { motionControllerState.IsTracked = true; lastMotionControllerTrackedTimestamp = currentTime.Ticks; } else { float timeSinceTracking = (float)currentTime.Subtract(new DateTime(lastMotionControllerTrackedTimestamp)).TotalSeconds; if (timeSinceTracking > profile.ControllerHideTimeout) { motionControllerState.IsTracked = false; } } }
private Vector3 GetCameraControlTranslation(Transform transform) { Vector3 deltaPosition = Vector3.zero; // Support fly up/down keypresses if the current project maps it. This isn't a standard // Unity InputManager mapping, so it has to gracefully fail if unavailable. if (this.isFlyKeypressEnabled) { try { deltaPosition += InputCurve(UnityEngine.Input.GetAxis("Fly")) * transform.up; } catch (System.Exception) { this.isFlyKeypressEnabled = false; } } else { // use page up/down in this case deltaPosition += GetKeyDir("page down", "page up") * Vector3.up; } deltaPosition += InputCurve(UnityEngine.Input.GetAxis(profile.MoveHorizontal)) * transform.right; Vector3 forward; Vector3 up; if (profile.CurrentControlMode == InputSimulationControlMode.Walk) { up = Vector3.up; forward = Vector3.ProjectOnPlane(transform.forward, up).normalized; } else { forward = transform.forward; up = transform.up; } deltaPosition += InputCurve(UnityEngine.Input.GetAxis(profile.MoveVertical)) * forward; deltaPosition += InputCurve(UnityEngine.Input.GetAxis(profile.MoveUpDown)) * up; float accel = KeyInputSystem.GetKey(profile.FastControlKey) ? profile.ControlFastSpeed : profile.ControlSlowSpeed; return(accel * deltaPosition * Time.deltaTime); }
private void Update() { bool shortcutPressed = true; bool shortcutDown = false; // Checks to make sure that all keys are pressed and that one of the required shortcut keys was pressed on this frame // before bringing up the shortcut foreach (KeyCode key in helpGuideShortcutKeys) { shortcutPressed &= KeyInputSystem.GetKey(KeyBinding.FromKey(key)); shortcutDown |= KeyInputSystem.GetKeyDown(KeyBinding.FromKey(key)); } if (shortcutPressed && shortcutDown) { helpGuideVisual.SetActive(!helpGuideVisual.activeSelf); helpGuideShortcutTip.SetActive(false); } }
/// <summary> /// Start or stop rotation based on the key binding. /// </summary> /// <remarks> /// Also manages shared features such as cursor visibility that can be activated by different rotation providers. /// </remarks> public void Update(KeyBinding rotationKey, KeyBinding cancelRotationKey, bool toggle) { bool wasRotating = isRotating; // Only allow the mouse to control rotation when Unity has focus. // This enables the player to temporarily alt-tab away without having the player // look around randomly back in the Unity Game window. if (!Application.isFocused) { isRotating = false; } else { if (toggle) { if (isRotating) { // Pressing escape will stop capture isRotating = !KeyInputSystem.GetKeyDown(cancelRotationKey); } else { // Capture focus when starting rotation isRotating = KeyInputSystem.GetKeyDown(rotationKey); } } else { // Rotate only while key is pressed isRotating = KeyInputSystem.GetKey(rotationKey); } } if (!wasRotating && isRotating) { OnStartRotating(rotationKey); } else if (wasRotating && !isRotating) { OnEndRotating(rotationKey); } }
private ArticulatedHandPose.GestureId ToggleGesture(ArticulatedHandPose.GestureId gesture) { // See comments in SelectGesture for why both the button down and gesture are checked. if (KeyInputSystem.GetKeyDown(profile.InteractionButton) && profile.LeftMouseHandGesture != ArticulatedHandPose.GestureId.None) { return(gesture != profile.LeftMouseHandGesture ? profile.LeftMouseHandGesture : profile.DefaultHandGesture); } else if (KeyInputSystem.GetKeyDown(profile.MouseLookButton) && profile.RightMouseHandGesture != ArticulatedHandPose.GestureId.None) { return(gesture != profile.RightMouseHandGesture ? profile.RightMouseHandGesture : profile.DefaultHandGesture); } else if (KeyInputSystem.GetKeyDown(KeyBinding.FromMouseButton(KeyBinding.MouseButton.Middle)) && profile.MiddleMouseHandGesture != ArticulatedHandPose.GestureId.None) { return(gesture != profile.MiddleMouseHandGesture ? profile.MiddleMouseHandGesture : profile.DefaultHandGesture); } else { // 'None' will not change the gesture return(ArticulatedHandPose.GestureId.None); } }
/// <summary> /// Update hand state based on keyboard and mouse input /// </summary> private void SimulateUserInput(MouseDelta mouseDelta) { float time = Time.time; if (KeyInputSystem.GetKeyDown(profile.ToggleLeftHandKey)) { IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft; } if (KeyInputSystem.GetKeyDown(profile.ToggleRightHandKey)) { IsAlwaysVisibleRight = !IsAlwaysVisibleRight; } if (!Application.isFocused && !KeyInputSystem.SimulatingInput) { isSimulatingLeft = false; isSimulatingRight = false; } else { if (KeyInputSystem.GetKeyDown(profile.LeftHandManipulationKey)) { isSimulatingLeft = true; if (lastSimulationLeft > 0.0f && time - lastSimulationLeft <= profile.DoublePressTime) { IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft; } lastSimulationLeft = time; } if (KeyInputSystem.GetKeyUp(profile.LeftHandManipulationKey)) { isSimulatingLeft = false; } if (KeyInputSystem.GetKeyDown(profile.RightHandManipulationKey)) { isSimulatingRight = true; if (lastSimulationRight > 0.0f && time - lastSimulationRight <= profile.DoublePressTime) { IsAlwaysVisibleRight = !IsAlwaysVisibleRight; } lastSimulationRight = time; } if (KeyInputSystem.GetKeyUp(profile.RightHandManipulationKey)) { isSimulatingRight = false; } if (isSimulatingGaze) { lastSimulationGaze = time; } } mouseRotation.Update(profile.HandRotateButton, cancelRotationKey, false); SimulateHandInput(ref lastHandTrackedTimestampLeft, HandStateLeft, isSimulatingLeft, IsAlwaysVisibleLeft, mouseDelta, mouseRotation.IsRotating); SimulateHandInput(ref lastHandTrackedTimestampRight, HandStateRight, isSimulatingRight, IsAlwaysVisibleRight, mouseDelta, mouseRotation.IsRotating); SimulateHandInput(ref lastHandTrackedTimestampGaze, HandStateGaze, isSimulatingGaze, false, mouseDelta, mouseRotation.IsRotating); // This line explicitly uses unscaledDeltaTime because we don't want input simulation // to lag when the time scale is set to a value other than 1. Input should still continue // to move freely. float gestureAnimDelta = profile.HandGestureAnimationSpeed * Time.unscaledDeltaTime; HandStateLeft.GestureBlending += gestureAnimDelta; HandStateRight.GestureBlending += gestureAnimDelta; HandStateGaze.GestureBlending = 1.0f; }