-
-
Notifications
You must be signed in to change notification settings - Fork 994
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(CameraRig): add ability to move camera rig with touchpad
The touchpad can now be used to move the play area in the direction the headset is facing. It can also be used to strafe left and right in the current facing direction. The new `SteamVR_TouchpadWalking` script is added to the `[CameraRig]` prefab and adds a box collider and a rigidbody to the camera rig to handle collisions. If the `SteamVR_HeadsetCollisionFade` script is also applied to the `[CameraRig]->Camera` then on collision of the headset with a game object, the user will have their position reset to their last good known position. To achieve this a new `HeadsetCollisionDetect` event has been added to the Headset Collision Fade script which the new Touchpad Walking script listens for. A big thanks to Reddit user `u/MisterDeum` for all the help with testing this feature and coming up with ideas to make it a decent feature to add to the toolkit. A new example scene has been added to demonstrate this feature.
- Loading branch information
1 parent
70b4b75
commit 3582c87
Showing
6 changed files
with
319 additions
and
3 deletions.
There are no files selected for viewing
Binary file not shown.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
202 changes: 202 additions & 0 deletions
202
Assets/SteamVR_Unity_Toolkit/Scripts/SteamVR_TouchpadWalking.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
using UnityEngine; | ||
using System.Collections; | ||
|
||
public class SteamVR_TouchpadWalking : MonoBehaviour { | ||
public float maxWalkSpeed = 3f; | ||
public float deceleration = 0.1f; | ||
public float headsetYOffset = 0.2f; | ||
public bool ignoreGrabbedCollisions = true; | ||
|
||
private float movementSpeed = 0f; | ||
private float strafeSpeed = 0f; | ||
private int listenerInitTries = 5; | ||
|
||
private Transform headset; | ||
private Vector2 touchAxis; | ||
|
||
private Rigidbody rb; | ||
private BoxCollider bc; | ||
|
||
private GameObject floorTouching; | ||
private Vector3 lastGoodPosition; | ||
private bool lastGoodPositionSet = false; | ||
private float highestHeadsetY = 0f; | ||
private float crouchMargin = 0.5f; | ||
private float lastPlayAreaY = 0f; | ||
|
||
private void Start () { | ||
this.name = "PlayerObject_" + this.name; | ||
lastGoodPositionSet = false; | ||
headset = GetHeadset(); | ||
CreateCollider(); | ||
InitListeners(); | ||
} | ||
|
||
private Transform GetHeadset() | ||
{ | ||
#if (UNITY_5_4_OR_NEWER) | ||
return GameObject.FindObjectOfType<SteamVR_Camera>().GetComponent<Transform>(); | ||
#endif | ||
return GameObject.FindObjectOfType<SteamVR_GameView>().GetComponent<Transform>(); | ||
} | ||
|
||
private void InitListeners() | ||
{ | ||
SteamVR_ControllerEvents[] controllers = GameObject.FindObjectsOfType<SteamVR_ControllerEvents>(); | ||
if (controllers.Length == 0) | ||
{ | ||
if (listenerInitTries > 0) | ||
{ | ||
listenerInitTries--; | ||
Invoke("InitListeners", 0.25f); | ||
} | ||
else | ||
{ | ||
Debug.LogError("A GameObject must exist with a SteamVR_ControllerEvents script attached to it"); | ||
return; | ||
} | ||
} | ||
|
||
foreach (SteamVR_ControllerEvents controller in controllers) | ||
{ | ||
controller.TouchpadAxisChanged += new ControllerClickedEventHandler(DoTouchpadAxisChanged); | ||
controller.TouchpadUntouched += new ControllerClickedEventHandler(DoTouchpadUntouched); | ||
|
||
if (ignoreGrabbedCollisions && controller.GetComponent<SteamVR_InteractGrab>()) | ||
{ | ||
SteamVR_InteractGrab grabbingController = controller.GetComponent<SteamVR_InteractGrab>(); | ||
grabbingController.ControllerGrabInteractableObject += new ObjectInteractEventHandler(OnGrabObject); | ||
grabbingController.ControllerUngrabInteractableObject += new ObjectInteractEventHandler(OnUngrabObject); | ||
} | ||
} | ||
|
||
if (headset.GetComponent<SteamVR_HeadsetCollisionFade>()) | ||
{ | ||
headset.GetComponent<SteamVR_HeadsetCollisionFade>().HeadsetCollisionDetect += new HeadsetCollisionEventHandler(OnHeadsetCollision); | ||
} | ||
} | ||
|
||
private void OnGrabObject(object sender, ObjectInteractEventArgs e) | ||
{ | ||
Physics.IgnoreCollision(this.GetComponent<Collider>(), e.target.GetComponent<Collider>(), true); | ||
} | ||
|
||
private void OnUngrabObject(object sender, ObjectInteractEventArgs e) | ||
{ | ||
Physics.IgnoreCollision(this.GetComponent<Collider>(), e.target.GetComponent<Collider>(), false); | ||
} | ||
|
||
private void OnHeadsetCollision(object sender, HeadsetCollisionEventArgs e) | ||
{ | ||
if (lastGoodPositionSet) { | ||
SteamVR_Fade.Start(Color.black, 0f); | ||
this.transform.position = lastGoodPosition; | ||
} | ||
} | ||
|
||
private void CreateCollider() | ||
{ | ||
rb = this.gameObject.AddComponent<Rigidbody>(); | ||
rb.mass = 100; | ||
rb.freezeRotation = true; | ||
|
||
bc = this.gameObject.AddComponent<BoxCollider>(); | ||
bc.center = new Vector3(0f, 1f, 0f); | ||
bc.size = new Vector3(0.25f, 1f, 0.25f); | ||
|
||
this.gameObject.layer = 2; | ||
} | ||
|
||
private void DoTouchpadAxisChanged(object sender, ControllerClickedEventArgs e) | ||
{ | ||
touchAxis = e.touchpadAxis; | ||
} | ||
|
||
private void DoTouchpadUntouched(object sender, ControllerClickedEventArgs e) | ||
{ | ||
touchAxis = Vector2.zero; | ||
} | ||
|
||
private void CalculateSpeed(ref float speed, float inputValue) | ||
{ | ||
if (inputValue != 0f) | ||
{ | ||
speed = (maxWalkSpeed * inputValue); | ||
} | ||
else | ||
{ | ||
Decelerate(ref speed); | ||
} | ||
} | ||
|
||
private void Decelerate(ref float speed) | ||
{ | ||
if (speed > 0) | ||
{ | ||
speed -= Mathf.Lerp(deceleration, maxWalkSpeed, 0f); | ||
} | ||
else if (speed < 0) | ||
{ | ||
speed += Mathf.Lerp(deceleration, -maxWalkSpeed, 0f); | ||
} | ||
else | ||
{ | ||
speed = 0; | ||
} | ||
} | ||
|
||
private void Move() | ||
{ | ||
Vector3 movement = headset.transform.forward * movementSpeed * Time.deltaTime; | ||
Vector3 strafe = headset.transform.right * strafeSpeed * Time.deltaTime; | ||
float fixY = this.transform.position.y; | ||
this.transform.position += (movement + strafe); | ||
this.transform.position = new Vector3(this.transform.position.x, fixY, this.transform.position.z); | ||
} | ||
|
||
private void UpdateCollider() | ||
{ | ||
float playAreaHeightAdjustment = 0.01f; | ||
float newBCYSize = (headset.transform.position.y - headsetYOffset) - this.transform.position.y; | ||
float newBCYCenter = (newBCYSize != 0 ? (newBCYSize / 2) + playAreaHeightAdjustment: 0); | ||
|
||
bc.size = new Vector3(bc.size.x, newBCYSize, bc.size.z); | ||
bc.center = new Vector3(headset.localPosition.x, newBCYCenter, headset.localPosition.z); | ||
} | ||
|
||
private void SetHeadsetY() | ||
{ | ||
//if the play area height has changed then always recalc headset height | ||
float floorVariant = 0.005f; | ||
if (this.transform.position.y > lastPlayAreaY + floorVariant || this.transform.position.y < lastPlayAreaY - floorVariant) | ||
{ | ||
highestHeadsetY = 0f; | ||
} | ||
|
||
if (headset.transform.position.y > highestHeadsetY) | ||
{ | ||
highestHeadsetY = headset.transform.position.y; | ||
} | ||
|
||
if (headset.transform.position.y > highestHeadsetY - crouchMargin) | ||
{ | ||
lastGoodPositionSet = true; | ||
lastGoodPosition = this.transform.position; | ||
} | ||
|
||
lastPlayAreaY = this.transform.position.y; | ||
} | ||
|
||
private void Update() | ||
{ | ||
SetHeadsetY(); | ||
UpdateCollider(); | ||
} | ||
|
||
private void FixedUpdate() | ||
{ | ||
CalculateSpeed(ref movementSpeed, touchAxis.y); | ||
CalculateSpeed(ref strafeSpeed, touchAxis.x); | ||
Move(); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
Assets/SteamVR_Unity_Toolkit/Scripts/SteamVR_TouchpadWalking.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters