Skip to content

Commit

Permalink
Zero-G rotation using VR camera / controller (depending on user setti…
Browse files Browse the repository at this point in the history
…ngs) (#391)

* Use VR to rotate player in zero G

* Better

* Fixed controller oriented movement

* Cleanup

* Disable zerog rotation while matching velocity
  • Loading branch information
Raicuparta authored Mar 11, 2021
1 parent dd4ae35 commit e35055f
Showing 1 changed file with 45 additions and 20 deletions.
65 changes: 45 additions & 20 deletions NomaiVR/Player/PlayerBodyPosition.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OWML.Utils;
using System;
using UnityEngine;

namespace NomaiVR
Expand All @@ -12,8 +13,11 @@ public class Behaviour : MonoBehaviour
{
private Transform _cameraParent;
private static Transform _playArea;
private Transform _camera;
private static OWCamera _playerCamera;
private static Animator _playerAnimator;
private static OWRigidbody _playerBody;
private static PlayerCharacterController _playerController;
private static Autopilot _autopilot;

internal void Start()
{
Expand All @@ -28,7 +32,12 @@ internal void Start()
AdjustPlayerHeadPosition();
SetupCamera();
CreateRecenterMenuEntry();
_playerAnimator = FindObjectOfType<PlayerAnimController>().GetValue<Animator>("_animator");
_playerBody = Locator.GetPlayerBody();
_playerAnimator = _playerBody.GetComponentInChildren<PlayerAnimController>().GetValue<Animator>("_animator");
_playerController = _playerBody.GetComponent<PlayerCharacterController>();
_autopilot = _playerBody.GetComponent<Autopilot>();
Logs.WriteInfo("_autopilot " + (_autopilot != null));
Logs.WriteInfo("_playerAnimator " + (_playerAnimator != null));
}

private static void AdjustPlayerHeadPosition()
Expand All @@ -40,24 +49,24 @@ private static void AdjustPlayerHeadPosition()
private void SetupCamera()
{
// Make an empty parent object for moving the camera around.
_camera = Camera.main.transform;
_playerCamera = Locator.GetPlayerCamera();
_cameraParent = new GameObject().transform;
_playArea = new GameObject().transform;
_playArea.parent = Locator.GetPlayerTransform();
_playArea.position = PlayerHelper.PlayerHead.position;
_playArea.rotation = PlayerHelper.PlayerHead.rotation;
_cameraParent.parent = _playArea;
_cameraParent.localRotation = Quaternion.identity;
_camera.parent = _cameraParent;
_playerCamera.transform.parent = _cameraParent;

var movement = PlayerHelper.PlayerHead.position - _camera.position;
var movement = PlayerHelper.PlayerHead.position - _playerCamera.transform.position;
_cameraParent.position += movement;

}

private void MoveCameraToPlayerHead()
{
var movement = PlayerHelper.PlayerHead.position - _camera.position;
var movement = PlayerHelper.PlayerHead.position - _playerCamera.transform.position;
_cameraParent.position += movement;
}

Expand All @@ -69,7 +78,7 @@ private void CreateRecenterMenuEntry()

internal void Update()
{
var cameraToHead = Vector3.ProjectOnPlane(PlayerHelper.PlayerHead.position - _camera.position, PlayerHelper.PlayerHead.up);
var cameraToHead = Vector3.ProjectOnPlane(PlayerHelper.PlayerHead.position - _playerCamera.transform.position, PlayerHelper.PlayerHead.up);

if (cameraToHead.sqrMagnitude > 0.5f)
{
Expand All @@ -92,30 +101,48 @@ public class Patch : NomaiVRPatch
{
public override void ApplyPatches()
{
Postfix<PlayerCharacterController>("UpdateTurning", nameof(Patch.PatchTurning));
Postfix<PlayerCharacterController>("UpdateTurning", nameof(Patch.PostCharacterTurning));
Postfix<JetpackThrusterController>("FixedUpdate", nameof(Patch.PostThrusterUpdate));
}

private static void PatchTurning(OWCamera ____playerCam, Transform ____transform)
private static void PostThrusterUpdate(Vector3 ____rotationalInput)
{
if (!PlayerState.InZeroG() || ____rotationalInput.sqrMagnitude != 0 || _autopilot.IsMatchingVelocity())
{
return;
}

_playerBody.SetAngularVelocity(Vector3.zero);

PatchTurning(rotation => _playerBody.MoveToRotation(rotation));
}

private static void PostCharacterTurning()
{
PatchTurning(rotation => _playerBody.transform.rotation = rotation);
}

private static void PatchTurning(Action<Quaternion> rotationSetter)
{
var runSpeedX = _playerAnimator.GetFloat("RunSpeedX");
var runSpeedY = _playerAnimator.GetFloat("RunSpeedY");
var isStopped = runSpeedX + runSpeedY == 0;
var isControllerOriented = !isStopped && ModSettings.ControllerOrientedMovement;
var isStoppedOnGround = _playerController.IsGrounded() && (runSpeedX + runSpeedY == 0);
var isControllerOriented = !(isStoppedOnGround) && ModSettings.ControllerOrientedMovement;

if ((OWInput.GetInputMode() != InputMode.Character))
{
return;
}

var rotationSource = isControllerOriented ? LaserPointer.Behaviour.LeftHandLaser : ____playerCam.transform;
var rotationSource = isControllerOriented ? LaserPointer.Behaviour.LeftHandLaser : _playerCamera.transform;

var fromTo = Quaternion.FromToRotation(____transform.forward, Vector3.ProjectOnPlane(rotationSource.transform.forward, ____transform.up));
var fromTo = Quaternion.FromToRotation(_playerBody.transform.forward, Vector3.ProjectOnPlane(rotationSource.transform.forward, _playerBody.transform.up));

var magnitude = 0f;
if (!isControllerOriented)
{
var magnitudeUp = 1 - Vector3.ProjectOnPlane(rotationSource.transform.up, ____transform.up).magnitude;
var magnitudeForward = 1 - Vector3.ProjectOnPlane(rotationSource.transform.up, ____transform.right).magnitude;
var magnitudeUp = 1 - Vector3.ProjectOnPlane(rotationSource.transform.up, _playerBody.transform.up).magnitude;
var magnitudeForward = 1 - Vector3.ProjectOnPlane(rotationSource.transform.up, _playerBody.transform.right).magnitude;
magnitude = magnitudeUp + magnitudeForward;

if (magnitude < 0.3f)
Expand All @@ -124,22 +151,20 @@ private static void PatchTurning(OWCamera ____playerCam, Transform ____transform
}
}

var targetRotation = fromTo * ____transform.rotation;
var targetRotation = fromTo * _playerBody.transform.rotation;
var inverseRotation = Quaternion.Inverse(fromTo) * _playArea.rotation;

if (isControllerOriented)
{
_playArea.rotation = inverseRotation;
____transform.rotation = targetRotation;
rotationSetter(targetRotation);
}
else
{
var maxDegreesDelta = magnitude * 3f;
_playArea.rotation = Quaternion.RotateTowards(_playArea.rotation, inverseRotation, maxDegreesDelta);
____transform.rotation = Quaternion.RotateTowards(____transform.rotation, targetRotation, maxDegreesDelta);
rotationSetter(Quaternion.RotateTowards(_playerBody.transform.rotation, targetRotation, maxDegreesDelta));
}


}
}

Expand Down

0 comments on commit e35055f

Please sign in to comment.