EVERYTHING
This commit is contained in:
@@ -0,0 +1,536 @@
|
||||
using System.Collections.Generic;
|
||||
using Photon.VR;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.XR;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion.Jump;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion.Movement;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion.Turning;
|
||||
|
||||
namespace BlockSpace.Voxels
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class DesktopRigController : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private Transform rigRoot;
|
||||
|
||||
[SerializeField]
|
||||
private Transform headTransform;
|
||||
|
||||
[SerializeField]
|
||||
private Transform leftHandTransform;
|
||||
|
||||
[SerializeField]
|
||||
private Transform rightHandTransform;
|
||||
|
||||
[SerializeField]
|
||||
private CharacterController characterController;
|
||||
|
||||
[SerializeField]
|
||||
private float mouseSensitivity = 2.25f;
|
||||
|
||||
[SerializeField]
|
||||
private float defaultMoveSpeed = 5f;
|
||||
|
||||
[SerializeField]
|
||||
private float defaultJumpHeight = 1.1f;
|
||||
|
||||
[SerializeField]
|
||||
private float handHorizontalOffset = 0.22f;
|
||||
|
||||
[SerializeField]
|
||||
private float handVerticalOffset = -0.18f;
|
||||
|
||||
[SerializeField]
|
||||
private float handForwardOffset = 0.35f;
|
||||
|
||||
[SerializeField]
|
||||
private float maxLookPitch = 85f;
|
||||
|
||||
[SerializeField]
|
||||
private float nonCreatorMoveSmoothing = 12f;
|
||||
|
||||
[SerializeField]
|
||||
private float creatorMoveSmoothing = 40f;
|
||||
|
||||
private readonly List<LocomotionProvider> vrLocomotionProviders = new List<LocomotionProvider>();
|
||||
|
||||
private readonly Dictionary<LocomotionProvider, bool> vrLocomotionStates = new Dictionary<LocomotionProvider, bool>();
|
||||
|
||||
private readonly List<TrackedPoseDriver> trackedPoseDrivers = new List<TrackedPoseDriver>();
|
||||
|
||||
private readonly Dictionary<TrackedPoseDriver, bool> trackedPoseDriverStates = new Dictionary<TrackedPoseDriver, bool>();
|
||||
|
||||
private readonly Dictionary<Collider, bool> phaseColliderStates = new Dictionary<Collider, bool>();
|
||||
|
||||
private ContinuousMoveProvider moveProvider;
|
||||
|
||||
private JumpProvider jumpProvider;
|
||||
|
||||
private ContinuousTurnProvider turnProvider;
|
||||
|
||||
private float verticalVelocity;
|
||||
|
||||
private float pitch;
|
||||
|
||||
private bool pitchInitialized;
|
||||
|
||||
private bool pcModeActive;
|
||||
|
||||
private Vector3 smoothedHorizontalVelocity;
|
||||
|
||||
private bool characterControllerCollisionCached;
|
||||
|
||||
private bool cachedCharacterControllerEnabled;
|
||||
|
||||
private bool cachedCharacterControllerDetectCollisions;
|
||||
|
||||
public void Configure(Transform trackingOrigin, Transform head, Transform leftHand, Transform rightHand)
|
||||
{
|
||||
if (trackingOrigin != null)
|
||||
{
|
||||
rigRoot = trackingOrigin;
|
||||
}
|
||||
if (head != null)
|
||||
{
|
||||
headTransform = head;
|
||||
}
|
||||
if (leftHand != null)
|
||||
{
|
||||
leftHandTransform = leftHand;
|
||||
}
|
||||
if (rightHand != null)
|
||||
{
|
||||
rightHandTransform = rightHand;
|
||||
}
|
||||
ResolveReferences();
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
ResolveReferences();
|
||||
RefreshLocomotionProviders();
|
||||
RefreshTrackedPoseDrivers();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
ResolveReferences();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
SetPcModeActive(active: false);
|
||||
RestoreCharacterControllerCollisions();
|
||||
UnlockCursor();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
ResolveReferences();
|
||||
bool flag = DetectXRInputActive();
|
||||
SetPcModeActive(!flag);
|
||||
if (!flag)
|
||||
{
|
||||
EnsureCursorLocked();
|
||||
HandleLook();
|
||||
HandleMovement();
|
||||
UpdateProxyHands();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResolveReferences()
|
||||
{
|
||||
if (rigRoot == null)
|
||||
{
|
||||
rigRoot = base.transform;
|
||||
}
|
||||
if (headTransform == null)
|
||||
{
|
||||
headTransform = ((Camera.main != null) ? Camera.main.transform : null);
|
||||
if (headTransform == null && PhotonVRManager.Manager != null)
|
||||
{
|
||||
headTransform = PhotonVRManager.Manager.Head;
|
||||
}
|
||||
}
|
||||
if (leftHandTransform == null && PhotonVRManager.Manager != null)
|
||||
{
|
||||
leftHandTransform = PhotonVRManager.Manager.LeftHand;
|
||||
}
|
||||
if (rightHandTransform == null && PhotonVRManager.Manager != null)
|
||||
{
|
||||
rightHandTransform = PhotonVRManager.Manager.RightHand;
|
||||
}
|
||||
if (characterController == null && rigRoot != null)
|
||||
{
|
||||
characterController = rigRoot.GetComponent<CharacterController>();
|
||||
if (characterController == null)
|
||||
{
|
||||
characterController = rigRoot.GetComponentInParent<CharacterController>();
|
||||
}
|
||||
if (characterController == null)
|
||||
{
|
||||
characterController = rigRoot.GetComponentInChildren<CharacterController>(includeInactive: true);
|
||||
}
|
||||
}
|
||||
if (characterController != null)
|
||||
{
|
||||
rigRoot = characterController.transform;
|
||||
}
|
||||
if (!pitchInitialized && headTransform != null)
|
||||
{
|
||||
pitch = NormalizeAngle(headTransform.localEulerAngles.x);
|
||||
pitchInitialized = true;
|
||||
}
|
||||
if (moveProvider == null)
|
||||
{
|
||||
ContinuousMoveProvider[] array = Object.FindObjectsByType<ContinuousMoveProvider>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
if (array.Length != 0)
|
||||
{
|
||||
moveProvider = array[0];
|
||||
}
|
||||
}
|
||||
if (jumpProvider == null)
|
||||
{
|
||||
JumpProvider[] array2 = Object.FindObjectsByType<JumpProvider>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
if (array2.Length != 0)
|
||||
{
|
||||
jumpProvider = array2[0];
|
||||
}
|
||||
}
|
||||
if (turnProvider == null)
|
||||
{
|
||||
ContinuousTurnProvider[] array3 = Object.FindObjectsByType<ContinuousTurnProvider>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
if (array3.Length != 0)
|
||||
{
|
||||
turnProvider = array3[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshLocomotionProviders()
|
||||
{
|
||||
vrLocomotionProviders.Clear();
|
||||
LocomotionProvider[] array = Object.FindObjectsByType<LocomotionProvider>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (LocomotionProvider locomotionProvider in array)
|
||||
{
|
||||
if (!(locomotionProvider == null) && !vrLocomotionProviders.Contains(locomotionProvider))
|
||||
{
|
||||
vrLocomotionProviders.Add(locomotionProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshTrackedPoseDrivers()
|
||||
{
|
||||
trackedPoseDrivers.Clear();
|
||||
TrackedPoseDriver[] array = Object.FindObjectsByType<TrackedPoseDriver>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (TrackedPoseDriver trackedPoseDriver in array)
|
||||
{
|
||||
if (!(trackedPoseDriver == null) && !trackedPoseDrivers.Contains(trackedPoseDriver))
|
||||
{
|
||||
trackedPoseDrivers.Add(trackedPoseDriver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPcModeActive(bool active)
|
||||
{
|
||||
if (pcModeActive == active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pcModeActive = active;
|
||||
if (pcModeActive)
|
||||
{
|
||||
RefreshLocomotionProviders();
|
||||
RefreshTrackedPoseDrivers();
|
||||
for (int i = 0; i < vrLocomotionProviders.Count; i++)
|
||||
{
|
||||
LocomotionProvider locomotionProvider = vrLocomotionProviders[i];
|
||||
if (!(locomotionProvider == null))
|
||||
{
|
||||
if (!vrLocomotionStates.ContainsKey(locomotionProvider))
|
||||
{
|
||||
vrLocomotionStates.Add(locomotionProvider, locomotionProvider.enabled);
|
||||
}
|
||||
locomotionProvider.enabled = false;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < trackedPoseDrivers.Count; j++)
|
||||
{
|
||||
TrackedPoseDriver trackedPoseDriver = trackedPoseDrivers[j];
|
||||
if (!(trackedPoseDriver == null))
|
||||
{
|
||||
if (!trackedPoseDriverStates.ContainsKey(trackedPoseDriver))
|
||||
{
|
||||
trackedPoseDriverStates.Add(trackedPoseDriver, trackedPoseDriver.enabled);
|
||||
}
|
||||
trackedPoseDriver.enabled = false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
foreach (KeyValuePair<LocomotionProvider, bool> vrLocomotionState in vrLocomotionStates)
|
||||
{
|
||||
if (vrLocomotionState.Key != null)
|
||||
{
|
||||
vrLocomotionState.Key.enabled = vrLocomotionState.Value;
|
||||
}
|
||||
}
|
||||
vrLocomotionStates.Clear();
|
||||
foreach (KeyValuePair<TrackedPoseDriver, bool> trackedPoseDriverState in trackedPoseDriverStates)
|
||||
{
|
||||
if (trackedPoseDriverState.Key != null)
|
||||
{
|
||||
trackedPoseDriverState.Key.enabled = trackedPoseDriverState.Value;
|
||||
}
|
||||
}
|
||||
trackedPoseDriverStates.Clear();
|
||||
verticalVelocity = 0f;
|
||||
}
|
||||
|
||||
private void HandleLook()
|
||||
{
|
||||
if (!(rigRoot == null) && !(headTransform == null))
|
||||
{
|
||||
float angle = Input.GetAxisRaw("Mouse X") * GetMouseLookSpeed();
|
||||
float num = Input.GetAxisRaw("Mouse Y") * GetMouseLookSpeed();
|
||||
rigRoot.Rotate(Vector3.up, angle, Space.World);
|
||||
pitch = Mathf.Clamp(pitch - num, 0f - maxLookPitch, maxLookPitch);
|
||||
headTransform.localRotation = Quaternion.Euler(pitch, 0f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMovement()
|
||||
{
|
||||
if (rigRoot == null || headTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool flag = VoxelGroupManager.Instance != null && !VoxelGroupManager.Instance.EditingLocked && VoxelGroupManager.Instance.CreatorMode;
|
||||
ApplyCharacterControllerPhase(flag);
|
||||
Vector2 zero = Vector2.zero;
|
||||
if (Input.GetKey(KeyCode.W))
|
||||
{
|
||||
zero.y += 1f;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.S))
|
||||
{
|
||||
zero.y -= 1f;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.D))
|
||||
{
|
||||
zero.x += 1f;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.A))
|
||||
{
|
||||
zero.x -= 1f;
|
||||
}
|
||||
if (zero.sqrMagnitude > 1f)
|
||||
{
|
||||
zero.Normalize();
|
||||
}
|
||||
Vector3 forward = headTransform.forward;
|
||||
Vector3 right = headTransform.right;
|
||||
if (!flag)
|
||||
{
|
||||
forward.y = 0f;
|
||||
right.y = 0f;
|
||||
}
|
||||
forward = ((forward.sqrMagnitude > 0.0001f) ? forward.normalized : Vector3.forward);
|
||||
right = ((right.sqrMagnitude > 0.0001f) ? right.normalized : Vector3.right);
|
||||
Vector3 b = (forward * zero.y + right * zero.x) * GetMoveSpeed();
|
||||
float b2 = ((VoxelGroupManager.Instance != null && !VoxelGroupManager.Instance.CreatorMode) ? nonCreatorMoveSmoothing : creatorMoveSmoothing);
|
||||
float t = 1f - Mathf.Exp((0f - Mathf.Max(0.01f, b2)) * Time.deltaTime);
|
||||
smoothedHorizontalVelocity = Vector3.Lerp(smoothedHorizontalVelocity, b, t);
|
||||
if (characterController != null)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
verticalVelocity = 0f;
|
||||
rigRoot.position += smoothedHorizontalVelocity * Time.deltaTime;
|
||||
return;
|
||||
}
|
||||
if (characterController.isGrounded && verticalVelocity < 0f)
|
||||
{
|
||||
verticalVelocity = -2f;
|
||||
}
|
||||
if (characterController.isGrounded && Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
verticalVelocity = Mathf.Sqrt(GetJumpHeight() * -2f * Physics.gravity.y);
|
||||
}
|
||||
verticalVelocity += Physics.gravity.y * Time.deltaTime;
|
||||
Vector3 vector = smoothedHorizontalVelocity + Vector3.up * verticalVelocity;
|
||||
characterController.Move(vector * Time.deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.Space) && Mathf.Abs(verticalVelocity) < 0.001f)
|
||||
{
|
||||
verticalVelocity = Mathf.Sqrt(GetJumpHeight() * -2f * Physics.gravity.y);
|
||||
}
|
||||
verticalVelocity += Physics.gravity.y * Time.deltaTime;
|
||||
rigRoot.position += (smoothedHorizontalVelocity + Vector3.up * verticalVelocity) * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateProxyHands()
|
||||
{
|
||||
if (!(headTransform == null))
|
||||
{
|
||||
Quaternion rotation = headTransform.rotation;
|
||||
Vector3 position = headTransform.TransformPoint(new Vector3(0f - handHorizontalOffset, handVerticalOffset, handForwardOffset));
|
||||
Vector3 position2 = headTransform.TransformPoint(new Vector3(handHorizontalOffset, handVerticalOffset, handForwardOffset));
|
||||
if (leftHandTransform != null)
|
||||
{
|
||||
leftHandTransform.SetPositionAndRotation(position, rotation);
|
||||
}
|
||||
if (rightHandTransform != null)
|
||||
{
|
||||
rightHandTransform.SetPositionAndRotation(position2, rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float GetMoveSpeed()
|
||||
{
|
||||
if (!(moveProvider != null))
|
||||
{
|
||||
return defaultMoveSpeed;
|
||||
}
|
||||
return moveProvider.moveSpeed;
|
||||
}
|
||||
|
||||
private float GetJumpHeight()
|
||||
{
|
||||
if (!(jumpProvider != null))
|
||||
{
|
||||
return defaultJumpHeight;
|
||||
}
|
||||
return jumpProvider.jumpHeight;
|
||||
}
|
||||
|
||||
private float GetMouseLookSpeed()
|
||||
{
|
||||
if (turnProvider == null)
|
||||
{
|
||||
return mouseSensitivity;
|
||||
}
|
||||
return turnProvider.turnSpeed / 180f * mouseSensitivity;
|
||||
}
|
||||
|
||||
private void ApplyCharacterControllerPhase(bool phaseThrough)
|
||||
{
|
||||
if (phaseThrough)
|
||||
{
|
||||
ApplyRigColliderPhase();
|
||||
if (characterController != null && !characterControllerCollisionCached)
|
||||
{
|
||||
cachedCharacterControllerEnabled = characterController.enabled;
|
||||
cachedCharacterControllerDetectCollisions = characterController.detectCollisions;
|
||||
characterControllerCollisionCached = true;
|
||||
}
|
||||
if (characterController != null)
|
||||
{
|
||||
characterController.enabled = false;
|
||||
characterController.detectCollisions = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreCharacterControllerCollisions();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyRigColliderPhase()
|
||||
{
|
||||
Collider[] componentsInChildren = ((rigRoot != null) ? rigRoot : base.transform).GetComponentsInChildren<Collider>(includeInactive: true);
|
||||
foreach (Collider collider in componentsInChildren)
|
||||
{
|
||||
if (!(collider == null) && !collider.isTrigger && !(collider is CharacterController))
|
||||
{
|
||||
if (!phaseColliderStates.ContainsKey(collider))
|
||||
{
|
||||
phaseColliderStates.Add(collider, collider.enabled);
|
||||
}
|
||||
collider.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreCharacterControllerCollisions()
|
||||
{
|
||||
if (!characterControllerCollisionCached || characterController == null)
|
||||
{
|
||||
characterControllerCollisionCached = false;
|
||||
RestoreRigColliderPhase();
|
||||
RestoreCharacterControllerForPcMovement();
|
||||
}
|
||||
else
|
||||
{
|
||||
characterController.enabled = cachedCharacterControllerEnabled;
|
||||
characterController.detectCollisions = cachedCharacterControllerDetectCollisions;
|
||||
characterControllerCollisionCached = false;
|
||||
RestoreRigColliderPhase();
|
||||
RestoreCharacterControllerForPcMovement();
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreCharacterControllerForPcMovement()
|
||||
{
|
||||
if (pcModeActive && !(characterController == null))
|
||||
{
|
||||
characterController.enabled = true;
|
||||
characterController.detectCollisions = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreRigColliderPhase()
|
||||
{
|
||||
foreach (KeyValuePair<Collider, bool> phaseColliderState in phaseColliderStates)
|
||||
{
|
||||
if (phaseColliderState.Key != null)
|
||||
{
|
||||
phaseColliderState.Key.enabled = phaseColliderState.Value;
|
||||
}
|
||||
}
|
||||
phaseColliderStates.Clear();
|
||||
}
|
||||
|
||||
private void EnsureCursorLocked()
|
||||
{
|
||||
if (Application.isFocused)
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnlockCursor()
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
Cursor.visible = true;
|
||||
}
|
||||
|
||||
private static float NormalizeAngle(float angle)
|
||||
{
|
||||
if (angle > 180f)
|
||||
{
|
||||
angle -= 360f;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
private static bool DetectXRInputActive()
|
||||
{
|
||||
if (!InputDevices.GetDeviceAtXRNode(XRNode.Head).isValid && !InputDevices.GetDeviceAtXRNode(XRNode.LeftHand).isValid)
|
||||
{
|
||||
return InputDevices.GetDeviceAtXRNode(XRNode.RightHand).isValid;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user