XRoom_Unity/Assets/Photon/FusionXRHost/Scripts/Rig/FusionRig.cs
2025-05-31 10:20:20 +03:30

179 lines
7.7 KiB
C#

using Fusion.Sockets;
using Fusion.XR.Host.Grabbing;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;
using BNG;
namespace Fusion.XR.Host.Rig
{
/**
*
* Hardware rig gives access to the various rig parts: head, left hand, right hand, and the play area, represented by the hardware rig itself
*
* Can be moved, either instantanesously, or with a camera fade
*
**/
public class FusionRig : MonoBehaviour, INetworkRunnerCallbacks
{
public HardwareHand leftHand;
public HardwareHand rightHand;
public HardwareHeadset headset;
public NetworkRunner runner;
public static FusionRig instance;
public enum RunnerExpectations
{
NoRunner, // For offline usages
PresetRunner,
DetectRunner // should not be used in multipeer scenario
}
public RunnerExpectations runnerExpectations = RunnerExpectations.DetectRunner;
bool searchingForRunner = false;
[Header("Input interpolation")]
public bool useInputInterpolation = false;
public float interpolationDelay = 0.008f;
XRHeadsetInputDevice headsetInputDevice;
XRControllerInputDevice leftHandInputDevice;
XRControllerInputDevice rightHandInputDevice;
public float InterpolationDelay => interpolationDelay;
public async Task<NetworkRunner> FindRunner()
{
while (searchingForRunner) await Task.Delay(10);
searchingForRunner = true;
if (runner == null && runnerExpectations != RunnerExpectations.NoRunner)
{
if (runnerExpectations == RunnerExpectations.PresetRunner || NetworkProjectConfig.Global.PeerMode == NetworkProjectConfig.PeerModes.Multiple)
{
Debug.LogWarning("Runner has to be set in the inspector to forward the input");
}
else
{
// Try to detect the runner
runner = FindObjectOfType<NetworkRunner>(true);
var searchStart = Time.time;
while (searchingForRunner && runner == null)
{
if (NetworkRunner.Instances.Count > 0)
{
runner = NetworkRunner.Instances[0];
}
if (runner == null)
{
await System.Threading.Tasks.Task.Delay(10);
}
}
}
}
searchingForRunner = false;
return runner;
}
protected virtual void Awake()
{
instance = this;
if (leftHand) leftHandInputDevice = leftHand.GetComponentInChildren<XRControllerInputDevice>();
if (rightHand) rightHandInputDevice = rightHand.GetComponentInChildren<XRControllerInputDevice>();
if (headset) headsetInputDevice = headset.GetComponentInChildren<XRHeadsetInputDevice>();
if (leftHandInputDevice == null || rightHandInputDevice == null || headsetInputDevice == null)
{
useInputInterpolation = false;
}
}
protected virtual async void Start()
{
await FindRunner();
if (runner)
{
runner.AddCallbacks(this);
}
}
private void OnDestroy()
{
if (searchingForRunner) Debug.LogError("Cancel searching for runner in HardwareRig");
searchingForRunner = false;
if (runner) runner.RemoveCallbacks(this);
}
public void Update()
{
GetComponentInChildren<SmoothLocomotion>().MovementForce = runner.IsConnectedToServer?1.25f: 0;
}
#region INetworkRunnerCallbacks
// Prepare the input, that will be read by NetworkRig in the FixedUpdateNetwork
public void OnInput(NetworkRunner runner, NetworkInput input) {
RigInput rigInput = new RigInput();
rigInput.playAreaPosition = transform.position;
rigInput.playAreaRotation = transform.rotation;
if (useInputInterpolation)
{
var leftHandInterpolationPose = leftHandInputDevice.InterpolatedPose(InterpolationDelay);
var rightHandInterpolationPose = rightHandInputDevice.InterpolatedPose(InterpolationDelay);
var headsetInterpolationPose = headsetInputDevice.InterpolatedPose(InterpolationDelay);
rigInput.leftHandPosition = leftHandInterpolationPose.position;
rigInput.leftHandRotation = leftHandInterpolationPose.rotation;
rigInput.rightHandPosition = rightHandInterpolationPose.position;
rigInput.rightHandRotation = rightHandInterpolationPose.rotation;
rigInput.headsetPosition = headsetInterpolationPose.position;
rigInput.headsetRotation = headsetInterpolationPose.rotation;
} else
{
rigInput.leftHandPosition = leftHand.transform.position;
rigInput.leftHandRotation = leftHand.transform.rotation;
rigInput.rightHandPosition = rightHand.transform.position;
rigInput.rightHandRotation = rightHand.transform.rotation;
rigInput.headsetPosition = headset.transform.position;
rigInput.headsetRotation = headset.transform.rotation;
}
rigInput.leftHandCommand = leftHand.handCommand;
rigInput.rightHandCommand = rightHand.handCommand;
rigInput.leftGrabInfo = leftHand.grabber.GrabInfo;
rigInput.rightGrabInfo = rightHand.grabber.GrabInfo;
input.Set(rigInput);
}
#endregion
#region INetworkRunnerCallbacks (unused)
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player) { }
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player) { }
public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input) { }
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason) { }
public void OnConnectedToServer(NetworkRunner runner) { }
public void OnDisconnectedFromServer(NetworkRunner runner, NetDisconnectReason reason) { }
public void OnConnectRequest(NetworkRunner runner, NetworkRunnerCallbackArgs.ConnectRequest request, byte[] token) { }
public void OnConnectFailed(NetworkRunner runner, NetAddress remoteAddress, NetConnectFailedReason reason) { }
public void OnUserSimulationMessage(NetworkRunner runner, SimulationMessagePtr message) { }
public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList) { }
public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data) { }
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) { }
public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ArraySegment<byte> data) { }
public void OnSceneLoadDone(NetworkRunner runner) { }
public void OnSceneLoadStart(NetworkRunner runner) { }
public void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player) { }
public void OnObjectExitAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player) { }
public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ReliableKey key, ArraySegment<byte> data) { }
public void OnReliableDataProgress(NetworkRunner runner, PlayerRef player, ReliableKey key, float progress) { }
#endregion
}
}