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

96 lines
3.3 KiB
C#

using UnityEngine;
namespace Fusion.XR.Host.Rig
{
public interface IHandRepresentation
{
public void SetHandCommand(HandCommand command);
public GameObject gameObject { get; }
public void SetHandColor(Color color);
public void SetHandMaterial(Material material);
public void DisplayMesh(bool shouldDisplay);
public bool IsMeshDisplayed { get; }
public Material SharedHandMaterial { get; }
}
/**
*
* Network VR user hand
*
* Handle the synchronisation of the hand pose
* Use the local HardwareRig rig hand pose when this rig is associated with the local user
*
* Position synchronization is handled in the NetworkRig
*
**/
[RequireComponent(typeof(NetworkTransform))]
[DefaultExecutionOrder(NetworkHand.EXECUTION_ORDER)]
public class NetworkHand : NetworkBehaviour
{
public const int EXECUTION_ORDER = NetworkRig.EXECUTION_ORDER + 10;
[HideInInspector]
public NetworkTransform networkTransform;
[Networked]
public HandCommand HandCommand { get; set; }
public RigPart side;
NetworkRig rig;
IHandRepresentation handRepresentation;
ChangeDetector changeDetector;
public bool IsLocalNetworkRig => rig.IsLocalNetworkRig;
public HardwareHand LocalHardwareHand => IsLocalNetworkRig ? (side == RigPart.LeftController ? rig.hardwareRig.leftHand : rig.hardwareRig.rightHand) : null;
private void Awake()
{
rig = GetComponentInParent<NetworkRig>();
networkTransform = GetComponent<NetworkTransform>();
handRepresentation = GetComponentInChildren<IHandRepresentation>();
}
public override void Spawned()
{
base.Spawned();
changeDetector = GetChangeDetector(ChangeDetector.Source.SnapshotFrom);
}
public override void Render()
{
base.Render();
if (IsLocalNetworkRig)
{
// Extrapolate for local user : we want to have the visual at the good position as soon as possible, so we force the visuals to follow the most fresh hand pose
UpdateRepresentationWithLocalHardwareState();
}
else
{
foreach (var changedNetworkedVarName in changeDetector.DetectChanges(this))
{
if (changedNetworkedVarName == nameof(HandCommand))
{
// Will be called when the local user change the hand pose structure
// We trigger here the actual animation update
UpdateHandRepresentationWithNetworkState();
}
}
}
}
// Update the hand representation each time the network structure HandCommand is updated
void UpdateHandRepresentationWithNetworkState()
{
if (handRepresentation != null) handRepresentation.SetHandCommand(HandCommand);
}
// Update the hand representation with the local hardware state
void UpdateRepresentationWithLocalHardwareState()
{
if (handRepresentation != null) handRepresentation.SetHandCommand(LocalHardwareHand.handCommand);
}
}
}