Files
BlockSpace-v1.5.0b/Assets/Scripts/Assembly-CSharp/BlockSpace/Worlds/CreatorFlightController.cs
T
2026-06-01 17:19:55 +02:00

202 lines
5.5 KiB
C#

using System.Collections.Generic;
using BlockSpace.Voxels;
using Photon.Pun;
using Photon.VR;
using UnityEngine;
using UnityEngine.XR;
namespace BlockSpace.Worlds
{
[DisallowMultipleComponent]
public sealed class CreatorFlightController : MonoBehaviour
{
[SerializeField]
private float flySpeed = 3.5f;
[SerializeField]
private float deadZone = 0.15f;
private InputDevice leftHand;
private bool flightProvidersDisabled;
private readonly Dictionary<Behaviour, bool> cachedProviderStates = new Dictionary<Behaviour, bool>();
private CharacterController phasedController;
private bool controllerCollisionCached;
private bool cachedControllerEnabled;
private bool cachedControllerDetectCollisions;
private void OnEnable()
{
leftHand = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
}
private void OnDisable()
{
RestoreProviders();
}
private void Update()
{
if (!PhotonNetwork.InRoom)
{
RestoreProviders();
return;
}
VoxelGroupManager instance = VoxelGroupManager.Instance;
if (instance == null || instance.EditingLocked || !instance.CreatorMode)
{
RestoreProviders();
RestoreCharacterControllerCollisions();
return;
}
DisableNonFlightProviders();
if (!leftHand.isValid)
{
leftHand = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
}
Vector2 value = Vector2.zero;
if (leftHand.isValid)
{
leftHand.TryGetFeatureValue(CommonUsages.primary2DAxis, out value);
}
if (Mathf.Abs(value.x) < deadZone)
{
value.x = 0f;
}
if (Mathf.Abs(value.y) < deadZone)
{
value.y = 0f;
}
Transform transform = ((PhotonVRManager.Manager != null) ? PhotonVRManager.Manager.Head : null);
Transform localVrTeleportRoot = PlayerTeleportUtil.GetLocalVrTeleportRoot();
if (!(transform == null) && !(localVrTeleportRoot == null))
{
Vector3 obj = ((transform.forward.sqrMagnitude > 0.0001f) ? transform.forward.normalized : Vector3.forward);
Vector3 vector = ((transform.right.sqrMagnitude > 0.0001f) ? transform.right.normalized : Vector3.right);
Vector3 vector2 = obj * value.y + vector * value.x;
if (vector2.sqrMagnitude > 1f)
{
vector2.Normalize();
}
CharacterController component = localVrTeleportRoot.GetComponent<CharacterController>();
if (component != null)
{
ApplyCharacterControllerPhase(component);
}
Vector3 vector3 = vector2 * flySpeed;
if (!(vector3.sqrMagnitude <= 0.0001f))
{
localVrTeleportRoot.position += vector3 * Time.deltaTime;
}
}
}
private void DisableNonFlightProviders()
{
if (flightProvidersDisabled)
{
return;
}
PhotonVRManager manager = PhotonVRManager.Manager;
if (!(manager == null))
{
cachedProviderStates.Clear();
cachedProviderStates.Clear();
DisableBehavioursUnder(manager.gameObject);
if (manager.LocalPlayer != null)
{
DisableBehavioursUnder(manager.LocalPlayer.gameObject);
}
if (manager.transform.root != null)
{
DisableBehavioursUnder(manager.transform.root.gameObject);
}
flightProvidersDisabled = true;
}
}
private void DisableBehavioursUnder(GameObject root)
{
if (root == null)
{
return;
}
Behaviour[] componentsInChildren = root.GetComponentsInChildren<Behaviour>(includeInactive: true);
foreach (Behaviour behaviour in componentsInChildren)
{
if (!(behaviour == null) && !(behaviour == this))
{
string text = behaviour.GetType().Name;
if (!string.IsNullOrEmpty(text) && !text.Contains("TurnProvider") && !text.Contains("SmoothTurn") && !text.Contains("SnapTurn") && (text.Contains("GravityProvider") || text.Contains("MoveProvider") || text.Contains("LocomotionProvider") || text.Contains("TeleportationProvider") || text.Contains("ClimbProvider") || text.Contains("ContinuousMove") || text.Contains("DynamicMove")))
{
cachedProviderStates[behaviour] = behaviour.enabled;
behaviour.enabled = false;
}
}
}
}
private void RestoreProviders()
{
if (!flightProvidersDisabled)
{
RestoreCharacterControllerCollisions();
return;
}
foreach (KeyValuePair<Behaviour, bool> cachedProviderState in cachedProviderStates)
{
if (cachedProviderState.Key != null)
{
cachedProviderState.Key.enabled = cachedProviderState.Value;
}
}
cachedProviderStates.Clear();
flightProvidersDisabled = false;
RestoreCharacterControllerCollisions();
}
private void ApplyCharacterControllerPhase(CharacterController controller)
{
if (!(controller == null))
{
if (phasedController != controller)
{
RestoreCharacterControllerCollisions();
phasedController = controller;
cachedControllerEnabled = controller.enabled;
cachedControllerDetectCollisions = controller.detectCollisions;
controllerCollisionCached = true;
}
controller.enabled = false;
controller.detectCollisions = false;
}
}
private void RestoreCharacterControllerCollisions()
{
if (controllerCollisionCached && phasedController != null)
{
phasedController.enabled = cachedControllerEnabled;
phasedController.detectCollisions = cachedControllerDetectCollisions;
EnsureControllerUsableAfterEdit(phasedController);
}
phasedController = null;
controllerCollisionCached = false;
}
private static void EnsureControllerUsableAfterEdit(CharacterController controller)
{
if (!(controller == null))
{
controller.enabled = true;
controller.detectCollisions = true;
}
}
}
}