From 039c823a8eeb20f516fe155854d975c96fae761b Mon Sep 17 00:00:00 2001 From: fangzhangmnm <1561797062@qq.com> Date: Wed, 11 Oct 2017 20:18:24 +0800 Subject: [PATCH 1/2] Update ArmSwinger.cs - Added support for SteamVR InteractionSystem's Player prefab. - New ArmSwingMode, just the one in VR Dungeon Knight! Left(Right)Touchpad - Activate by touching left(right) Touchpad. Move direction decided by touch position --- scripts/ArmSwinger.cs | 207 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 169 insertions(+), 38 deletions(-) diff --git a/scripts/ArmSwinger.cs b/scripts/ArmSwinger.cs index 8b0fbc8..bf2104b 100755 --- a/scripts/ArmSwinger.cs +++ b/scripts/ArmSwinger.cs @@ -1,7 +1,8 @@ -using UnityEngine; +using UnityEngine; using System.Collections; using System.Collections.Generic; using Valve.VR; +using Valve.VR.InteractionSystem; public class ArmSwinger : MonoBehaviour { @@ -19,16 +20,19 @@ public class ArmSwinger : MonoBehaviour { public bool generalScaleWorldUnitsToCameraRigScale = false; [Tooltip("General - Auto Adjust Fixed Timestep\n\nIn order for ArmSwinger to handle movement and wall collisions correctly, Time.fixedDeltaTime must be 0.0111 (90 per second) or less. If this feature is enabled, the setting will be adjusted automatically if it is higher than 0.0111. If disabled, an error will be generated but the value will not be changed.\n\n(Default: true)")] public bool generalAutoAdjustFixedTimestep = true; + [Tooltip("General - Set Player prefab's head collider to dynamic rigid body")] + public bool generalSetPlayerHeadColliderDynamic = true; // Arm Swing Settings [Header("Arm Swing Settings")] [Tooltip("Arm Swing - Navigation\n\nEnables variable locomotion using the controllers to determine speed and direction. Activated according to the selected Mode. \n\n(Default: true)")] public bool armSwingNavigation = true; + [SerializeField] [Tooltip("Arm Swing - Button\nOnly if Arm Swing Navigation is enabled\n\nDefines which controller button is used to activate ArmSwinger. The button is the same on both controllers.\n\n(Default: Grip button)")] private ControllerButton _armSwingButton = ControllerButton.Grip; [SerializeField] - [Tooltip("Arm Swing - Mode\nOnly if Arm Swing Navigation is enabled\n\nDetermines what is necessary to activate arm swing locomotion, and what controller is used when determining speed/direction.\n\nBoth Buttons Both Controllers - Activate by pushing both buttons on both controllers. Both controllers are used for speed/direction.\n\nLeft Button Both Controllers - Activate by pushing the left controller button. Both controllers are used for speed/direction.\n\nRight Button Both Controllers - Activate by pushing the right controller button. Both controllers are used for speed/direction.\n\nOne Button Same Controller - Activate by pushing either controller's button. That controller is used for speed/direction. Can be combined with the other controller.\n\nOne Button Same Controller Exclusive - Activate by pushing either controller's button. That controller is used for speed/direction. Squeezing the button on the other controller will have no effect until the first controller button is released.\n\n(Default: One Button Same Controller)")] + [Tooltip("Arm Swing - Mode\nOnly if Arm Swing Navigation is enabled\n\nDetermines what is necessary to activate arm swing locomotion, and what controller is used when determining speed/direction.\n\nBoth Buttons Both Controllers - Activate by pushing both buttons on both controllers. Both controllers are used for speed/direction.\n\nLeft Button Both Controllers - Activate by pushing the left controller button. Both controllers are used for speed/direction.\n\nRight Button Both Controllers - Activate by pushing the right controller button. Both controllers are used for speed/direction.\n\nOne Button Same Controller - Activate by pushing either controller's button. That controller is used for speed/direction. Can be combined with the other controller.\n\nOne Button Same Controller Exclusive - Activate by pushing either controller's button. That controller is used for speed/direction. Squeezing the button on the other controller will have no effect until the first controller button is released.\n\nLeft(Right)Touchpad - Activate by touching left(right) Touchpad. Move direction decided by touch position \n\n(Default: One Button Same Controller)")] private ArmSwingMode _armSwingMode = ArmSwingMode.OneButtonSameController; [Tooltip("Arm Swing - Controller To Movement Curve\nOnly if Arm Swing Navigation is enabled.\n\nCurve that determines how much a given controller change translates into camera rig movement. The far left of the curve is no controller movement and no virtual movement. The far right is Controller Speed For Max Speed (controller movement) and Max Speed (virtual momvement).\n\n(Default: Linear)")] public AnimationCurve armSwingControllerToMovementCurve = new AnimationCurve(new Keyframe(0, 0, 1, 1), new Keyframe(1, 1, 1, 1)); @@ -174,7 +178,9 @@ public enum ArmSwingMode { LeftButtonBothControllers, RightButtonBothControllers, OneButtonSameController, - OneButtonSameControllerExclusive + OneButtonSameControllerExclusive, + LeftTouchpad, + RightTouchpad, }; public enum ControllerButton { @@ -271,16 +277,26 @@ public enum ControllerSmoothingMode { Lowest, Average, AverageMinusHighest }; private bool leftButtonPressed = false; private bool rightButtonPressed = false; + private bool leftTouchpadTouched = false; + private bool leftTouchpadPressed = false; + private Vector2 leftTouchPosition=Vector2.zero; + private bool rightTouchpadTouched = false; + private bool rightTouchpadPressed = false; + private Vector2 rightTouchPosition=Vector2.zero; + + //// Controllers //// private SteamVR_ControllerManager controllerManager; - private GameObject leftControllerGameObject; - private GameObject rightControllerGameObject; private SteamVR_TrackedObject leftControllerTrackedObj; private SteamVR_TrackedObject rightControllerTrackedObj; private SteamVR_Controller.Device leftController; private SteamVR_Controller.Device rightController; - private int leftControllerIndex; - private int rightControllerIndex; + private int leftControllerIndex=-1; + private int rightControllerIndex=-1; + + private GameObject leftControllerGameObject; + private GameObject rightControllerGameObject; + private Player player; // Wall Clip tracking [HideInInspector] @@ -304,19 +320,45 @@ public enum ControllerSmoothingMode { Lowest, Average, AverageMinusHighest }; // Camera Rig scaling private float cameraRigScaleModifier = 1.0f; - + + void AssignHands(){ + if (player.leftHand != null) + leftControllerGameObject = player.leftHand.gameObject; + else if (player.rightHand != null) + leftControllerGameObject = player.rightHand.otherHand.gameObject; + else + leftControllerGameObject = player.hands [0].gameObject; + + if (player.rightHand != null) + rightControllerGameObject = player.rightHand.gameObject; + else if (player.leftHand != null) + rightControllerGameObject = player.leftHand.otherHand.gameObject; + else + rightControllerGameObject = player.hands [1].gameObject; + } + /****** INITIALIZATION ******/ void Awake() { // Find an assign components and objects - controllerManager = this.GetComponent(); - leftControllerGameObject = controllerManager.left; - rightControllerGameObject = controllerManager.right; - leftControllerTrackedObj = leftControllerGameObject.GetComponent(); - rightControllerTrackedObj = rightControllerGameObject.GetComponent(); + + player = GetComponent (); + //Decide Whether it is attached to a Player or a CameraRig prefab + if(player!=null){ + AssignHands (); + headsetGameObject = player.headCollider.gameObject; + cameraRigGameObject = player.gameObject; + }else{ + controllerManager = this.GetComponent(); + leftControllerGameObject = controllerManager.left; + rightControllerGameObject = controllerManager.right; + leftControllerTrackedObj = leftControllerGameObject.GetComponent(); + rightControllerTrackedObj = rightControllerGameObject.GetComponent(); + + headsetGameObject = GameObject.FindObjectOfType().gameObject; + cameraRigGameObject = GameObject.FindObjectOfType().gameObject; + } - headsetGameObject = GameObject.FindObjectOfType().gameObject; - cameraRigGameObject = GameObject.FindObjectOfType().gameObject; // Determine the Steam VR button for ArmSwinging steamVRArmSwingButton = convertControllerButtonToSteamVRButton(armSwingButton); @@ -372,6 +414,9 @@ void FixedUpdate() { } // Store controller button states + if(player!=null) + AssignHands (); + getControllerButtons(); // reset this frame counters @@ -424,8 +469,8 @@ void FixedUpdate() { void verifySettings() { // Camera Rig checking - if (!this.GetComponent()) { - Debug.LogError("ArmSwinger.verifySettings():: ArmSwinger is applied on a GameObject that is not a SteamVR CameraRig, or is a CameraRig without a SteamVR Controller Manager. Please review the ArmSwinger instructions. ArmSwinger will fail."); + if (player==null && !this.GetComponent()) { + Debug.LogError("ArmSwinger.verifySettings():: ArmSwinger is applied on a GameObject that is not a SteamVR CameraRig, or is a CameraRig without a SteamVR Controller Manager or Player. Please review the ArmSwinger instructions. ArmSwinger will fail."); } // Rewind Settings @@ -483,6 +528,12 @@ Vector3 variableArmSwingMotion() { case ArmSwingMode.OneButtonSameControllerExclusive: movedThisFrame = swingOneButtonSameControllerExclusive(ref movementAmount, ref movementRotation); break; + case ArmSwingMode.LeftTouchpad: + movedThisFrame=swingLeftRightTouchpad(ref movementAmount, ref movementRotation); + break; + case ArmSwingMode.RightTouchpad: + movedThisFrame=swingLeftRightTouchpad(ref movementAmount, ref movementRotation); + break; } if (movedThisFrame) { @@ -519,7 +570,63 @@ Vector3 variableArmSwingMotion() { return Vector3.zero; } } + bool swingLeftRightTouchpad(ref float movement, ref Quaternion rotation) { + + if (armSwingMode== ArmSwingMode.LeftTouchpad && leftTouchpadTouched || + armSwingMode== ArmSwingMode.RightTouchpad && rightTouchpadTouched) { + // Find the change in controller position since last Update() + float leftControllerChange = Vector3.Distance(leftControllerPreviousLocalPosition, leftControllerLocalPosition); + float rightControllerChange = Vector3.Distance(rightControllerPreviousLocalPosition, rightControllerLocalPosition); + + // Calculate what camera rig movement the change should be converted to + float leftMovement = calculateMovement(armSwingControllerToMovementCurve, leftControllerChange, armSwingControllerSpeedForMaxSpeed, armSwingMaxSpeed); + float rightMovement = calculateMovement(armSwingControllerToMovementCurve, rightControllerChange, armSwingControllerSpeedForMaxSpeed, armSwingMaxSpeed); + + // Controller movement is the average of the two controllers' change times the both controllers coefficient + float controllerMovement = (leftMovement + rightMovement) / 2 * armSwingBothControllersCoefficient; + + // If movingInertia is enabled, the higher of inertia or controller movement is used + if (movingInertia) { + movement = movingInertiaOrControllerMovement(controllerMovement); + } + else { + movement = controllerMovement; + } + + Transform t; + Vector2 i; + if (armSwingMode== ArmSwingMode.LeftTouchpad){ + t=leftControllerGameObject.transform; + i=leftTouchPosition; + } + else + { + t=rightControllerGameObject.transform; + i=rightTouchPosition; + } + var ii = i.x * t.right + i.y * t.forward; + var v = Quaternion.FromToRotation (t.up, Vector3.up) * ii; + + movement *= v.magnitude; + rotation = Quaternion.FromToRotation (Vector3.forward, v); + + return true; + } + // If stopping inertia is enabled + else if (stoppingInertia && latestArtificialMovement != 0) { + + // The rotation is the cached one + rotation = latestArtificialRotation; + // The stopping movement is calculated using a curve, the latest movement, last frame's deltaTime, max speed, and the stop time for max speed + movement = inertiaMovementChange(stoppingInertiaCurve, latestArtificialMovement, previousTimeDeltaTime, armSwingMaxSpeed, stoppingInertiaTimeToStopAtMaxSpeed); + + return true; + } + else { + return false; + } + } // Arm Swing when armSwingMode is BothButtonsBothControllers bool swingBothButtonsBothControllers(ref float movement, ref Quaternion rotation) { if (leftButtonPressed && rightButtonPressed) { @@ -1439,33 +1546,52 @@ void decrementPushBackOverride() { // Sets the button variables each frame void getControllerButtons() { - // Left - int newLeftControllerIndex = (int) leftControllerTrackedObj.index; + if(player!=null){ + leftController = player.leftController; + rightController = player.rightController; + } + else + { + // Left + int newLeftControllerIndex = (int) leftControllerTrackedObj.index; + + if (newLeftControllerIndex != -1 && newLeftControllerIndex != leftControllerIndex) { + leftControllerIndex = newLeftControllerIndex; + leftController = SteamVR_Controller.Input(leftControllerIndex); + } - if (newLeftControllerIndex != -1 && newLeftControllerIndex != leftControllerIndex) { - leftControllerIndex = newLeftControllerIndex; - leftController = SteamVR_Controller.Input(leftControllerIndex); - } + if (newLeftControllerIndex == -1) + leftController=null; - if (newLeftControllerIndex != -1) { - leftButtonPressed = leftController.GetPress(steamVRArmSwingButton); - } - else { - leftButtonPressed = false; - } + //Right + int newRightControllerIndex = (int) rightControllerTrackedObj.index; - //Right - int newRightControllerIndex = (int) rightControllerTrackedObj.index; + if (newRightControllerIndex != -1 && newRightControllerIndex != rightControllerIndex) { + rightControllerIndex = newRightControllerIndex; + rightController = SteamVR_Controller.Input(rightControllerIndex); + } - if (newRightControllerIndex != -1 && newRightControllerIndex != rightControllerIndex) { - rightControllerIndex = newRightControllerIndex; - rightController = SteamVR_Controller.Input(rightControllerIndex); + if (newRightControllerIndex == -1) + rightController=null; } - - if (newRightControllerIndex != -1) { - rightButtonPressed = rightController.GetPress(steamVRArmSwingButton); + if (leftController != null) { + leftTouchpadTouched = leftController.GetTouch (EVRButtonId.k_EButton_SteamVR_Touchpad); + leftTouchpadPressed = leftController.GetPress (EVRButtonId.k_EButton_SteamVR_Touchpad); + leftTouchPosition = leftController.GetAxis (EVRButtonId.k_EButton_SteamVR_Touchpad); + leftButtonPressed = leftController.GetPress (steamVRArmSwingButton); + } else { + leftButtonPressed = false; + leftTouchPosition = Vector2.zero; + leftButtonPressed = false; } - else { + if (rightController != null) { + rightTouchpadTouched = rightController.GetTouch (EVRButtonId.k_EButton_SteamVR_Touchpad); + rightTouchpadPressed = rightController.GetPress (EVRButtonId.k_EButton_SteamVR_Touchpad); + rightTouchPosition = rightController.GetAxis (EVRButtonId.k_EButton_SteamVR_Touchpad); + rightButtonPressed = rightController.GetPress (steamVRArmSwingButton); + } else { + rightButtonPressed = false; + rightTouchPosition = Vector2.zero; rightButtonPressed = false; } } @@ -1652,6 +1778,11 @@ bool isDistanceFarEnough(Vector3 position1, Vector3 position2, float minDistance // Adds the Collider script to the headset if it doesn't already exist void setupHeadsetCollider() { + if (player != null && generalSetPlayerHeadColliderDynamic) { + var rb = headsetGameObject.GetComponent (); + rb.isKinematic = false; + rb.constraints = RigidbodyConstraints.FreezeAll; + } headsetCollider = headsetGameObject.GetComponent(); if (!headsetCollider) { headsetCollider = headsetGameObject.AddComponent(); From 221f2bd056b62feba1385d4cb026e5cc281a1f67 Mon Sep 17 00:00:00 2001 From: fangzhangmnm <1561797062@qq.com> Date: Wed, 11 Oct 2017 20:26:39 +0800 Subject: [PATCH 2/2] New integration and New Arm Swing Mode! - Add integration to SteamVR Interaction System's Player Prefab - New Arm Swing Mode, just the one in VR Dungeon Knight! Now you can control movement direction by touchpad! --- scripts/ArmSwinger.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ArmSwinger.cs b/scripts/ArmSwinger.cs index bf2104b..c26777b 100755 --- a/scripts/ArmSwinger.cs +++ b/scripts/ArmSwinger.cs @@ -41,7 +41,7 @@ public class ArmSwinger : MonoBehaviour { private float _armSwingControllerSpeedForMaxSpeed = 3f; [SerializeField] [Tooltip("Arm Swing - Max Speed\nOnly if Arm Swing Navigation is enabled\n\nThe fastest base speed (in world units) a player can travel when moving controllers at Controller Movement Per Second For Max Speed. The actual max speed of the player will depend on the both/single controller coefficients you configure.\n\n(Default: 8)")] - private float _armSwingMaxSpeed = 8; + private float _armSwingMaxSpeed = 8; [Tooltip("Arm Swing - Both Controllers Coefficient\nOnly if Arm Swing Navigation is enabled and Swing Activation Mode allows both controllers to be used for arm swinging.\n\nUsed to boost or nerf the player's speed when using boths controllers for arm swinging. A value of 1.0 will not modify the curve / max speed calculation.\n\n(Default: 1.0)")] [Range(0f, 10f)] [SerializeField]