Initial commit

This commit is contained in:
Thorbjoern
2025-05-26 00:46:28 +02:00
commit e5bca03433
3896 changed files with 1434297 additions and 0 deletions
@@ -0,0 +1,24 @@
using UnityEngine;
using Unity.Netcode.Components;
namespace XRMultiplayer
{
/// <summary>
/// ClientNetworkTransform class is responsible for updating the
/// <see cref="NetworkTransform"/> from the local owner perspective.
/// </summary>
[DisallowMultipleComponent]
public class ClientNetworkTransform : NetworkTransform
{
/// <summary>
/// If true, only the Server can update the transform of the object.
/// </summary>
[SerializeField, Tooltip("Determines Local or Server transform updating.")] bool isServerAuthoritative = false;
///<inheritdoc/>
protected override bool OnIsServerAuthoritative()
{
return isServerAuthoritative;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 25f7d6f3d19b0524d9be4bc50efbc19a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,26 @@
using UnityEngine;
using Unity.Netcode;
using Unity.XR.CoreUtils;
using UnityEngine.Events;
/// <summary>
/// Simple Network Trigger syncing the events over the network when the local player enters the trigger collider.
/// </summary>
public class NetworkTrigger : NetworkBehaviour
{
[SerializeField, Tooltip("This event is triggered when the Local Player walks into this.")] protected UnityEvent<ulong> m_NetworkedTriggerUnityEvent;
void OnTriggerEnter(Collider other)
{
// Local Player Triggered
if (other.TryGetComponent(out XROrigin origin))
{
TriggerRpc(NetworkManager.Singleton.LocalClientId);
}
}
[Rpc(SendTo.Everyone)]
void TriggerRpc(ulong clientId)
{
m_NetworkedTriggerUnityEvent?.Invoke(clientId);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 70a0910909cd7314eb658649e9e0375d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: db5f8a51ece76e84492ef6b20cddc4b3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,60 @@
using UnityEngine;
using Unity.Netcode;
using UnityEngine.UI;
namespace XRMultiplayer
{
/// <summary>
/// Simple implementation of a Networked button.
/// </summary>
[RequireComponent(typeof(Button))]
public class NetworkedButton : NetworkBehaviour
{
/// <summary>
/// Button associated with this component.
/// </summary>
Button m_Button;
///<inheritdoc/>
private void Awake()
{
m_Button = GetComponent<Button>();
m_Button.onClick.AddListener(ButtonClicked);
}
/// <summary>
/// Called when the button is clicked by the Local user.
/// </summary>
void ButtonClicked()
{
ClickButtonServerRpc(NetworkManager.Singleton.LocalClientId);
}
/// <summary>
/// Called from the local user to the Server when the local user has clicked the button.
/// </summary>
/// <param name="clientId">Local user Id.</param>
[ServerRpc(RequireOwnership = false)]
void ClickButtonServerRpc(ulong clientId)
{
ClickButtonClientRpc(clientId);
}
/// <summary>
/// Called from the Server on all clients after a local user has clicked the button.
/// </summary>
/// <param name="clientId">Local user Id.</param>
[ClientRpc]
void ClickButtonClientRpc(ulong clientId)
{
// Don't update on the local client if they sent the call.
if (NetworkManager.Singleton.LocalClientId != clientId)
{
//Remove listener here before Invoking to prevent continuous looping
m_Button.onClick.RemoveListener(ButtonClicked);
m_Button.onClick.Invoke();
m_Button.onClick.AddListener(ButtonClicked);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01970be37ab42be46b7bd0691f6f970d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,88 @@
using UnityEngine;
using Unity.Netcode;
using TMPro;
namespace XRMultiplayer
{
/// <summary>
/// Simple implementation of a Networked Dropdown.
/// </summary>
[RequireComponent(typeof(TMP_Dropdown))]
public class NetworkedDropdown : NetworkBehaviour
{
[SerializeField, Tooltip("Broadcast the value of the dropdown to all clients when a new client joins.")]
bool m_BroadcastValueOnJoin = false;
/// <summary>
/// Networked Variable to sync the state of the dropdown on new clients joining.
/// </summary>
NetworkVariable<int> m_CurrentDropdownNetworkValue;
/// <summary>
/// Dropdown associated with this component.
/// </summary>
TMP_Dropdown m_Dropdown;
///<inheritdoc/>
private void Awake()
{
m_Dropdown = GetComponent<TMP_Dropdown>();
m_CurrentDropdownNetworkValue = new NetworkVariable<int>(m_Dropdown.value, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
m_Dropdown.onValueChanged.AddListener(UpdateDropdown);
}
///<inheritdoc/>
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (m_BroadcastValueOnJoin)
{
// Sync the value of the dropdown.
m_Dropdown.value = m_CurrentDropdownNetworkValue.Value;
}
else
{
m_Dropdown.SetValueWithoutNotify(m_CurrentDropdownNetworkValue.Value);
}
}
/// <summary>
/// Called when the Dropdown is updated by the local user.
/// </summary>
/// <param name="dropdownValue">Value of the dropdown.</param>
void UpdateDropdown(int dropdownValue)
{
UpdateDropdownServerRpc(dropdownValue, NetworkManager.Singleton.LocalClientId);
}
/// <summary>
/// Called from the local user to the Server whe the local user has updated the slider.
/// </summary>
/// <param name="dropdownValue">Value of the dropdown.</param>
/// <param name="clientId">Local user Id.</param>
[ServerRpc(RequireOwnership = false)]
void UpdateDropdownServerRpc(int dropdownValue, ulong clientId)
{
UpdateDropdownClientRpc(dropdownValue, clientId);
}
/// <summary>
/// Called from the Server on all clients when a local user has updated the dropdown.
/// </summary>
/// <param name="dropdownValue">Value of the dropdown.</param>
/// <param name="clientId">Local user Id.</param>
[ClientRpc]
void UpdateDropdownClientRpc(int dropdownValue, ulong clientId)
{
// Don't update on the local client if they sent the call.
if (NetworkManager.Singleton.LocalClientId != clientId)
{
//Remove listener here before updating value to prevent continuous looping
m_Dropdown.onValueChanged.RemoveListener(UpdateDropdown);
m_Dropdown.value = dropdownValue;
m_Dropdown.onValueChanged.AddListener(UpdateDropdown);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 65eb984d014f1934da0f38f32923b9e8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,105 @@
using UnityEngine;
using Unity.Netcode;
using UnityEngine.UI;
namespace XRMultiplayer
{
/// <summary>
/// Simple implmentation of a Networked Slider.
/// </summary>
[RequireComponent(typeof(Slider))]
public class NetworkedSlider : NetworkBehaviour
{
[SerializeField, Tooltip("Broadcast the value of the dropdown to all clients when a new client joins.")]
bool m_BroadcastValueOnJoin = false;
[SerializeField, Tooltip("Reset current value when despawning.")]
bool m_ResetValueOnDespawn = true;
/// <summary>
/// Networked Variable to sync the state of the Slider on new clients joining.
/// </summary>
NetworkVariable<float> m_NetworkSliderValue;
/// <summary>
/// Slider associated with this component.
/// </summary>
Slider m_Slider;
float m_StartValue;
///<inheritdoc/>
private void Awake()
{
m_Slider = GetComponent<Slider>();
m_Slider.onValueChanged.AddListener(SliderChanged);
m_StartValue = m_Slider.value;
m_NetworkSliderValue = new NetworkVariable<float>(m_StartValue, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
}
///<inheritdoc/>
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (m_BroadcastValueOnJoin)
{
// Sync the value of the dropdown.
m_Slider.value = m_NetworkSliderValue.Value;
}
else
{
m_Slider.SetValueWithoutNotify(m_NetworkSliderValue.Value);
}
}
public override void OnNetworkDespawn()
{
base.OnNetworkDespawn();
if (IsServer && m_ResetValueOnDespawn)
{
if (m_NetworkSliderValue != null)
m_NetworkSliderValue.Value = m_StartValue;
}
}
/// <summary>
/// Called when the Slider is updated by the local user.
/// </summary>
/// <param name="newValue">Value of the slider.</param>
void SliderChanged(float newValue)
{
SliderChangedServerRpc(newValue, NetworkManager.Singleton.LocalClientId);
}
/// <summary>
/// Called from the local user to the Server when the local user has updated the slider.
/// </summary>
/// <param name="newValue">Value of the slider.</param>
/// <param name="clientId">Local user Id.</param>
[ServerRpc(RequireOwnership = false)]
void SliderChangedServerRpc(float newValue, ulong clientId)
{
m_NetworkSliderValue.Value = newValue;
SliderChangedClientRpc(newValue, clientId);
}
/// <summary>
/// Called from the Server on all clients after a local user has updated the slider.
/// </summary>
/// <param name="newValue">Value of the slider.</param>
/// <param name="clientId">Local user Id.</param>
[ClientRpc]
void SliderChangedClientRpc(float newValue, ulong clientId)
{
// Don't update on the local client if they sent the call.
if (NetworkManager.Singleton.LocalClientId != clientId)
{
//Remove listener here before updating value to prevent continuous looping
m_Slider.onValueChanged.RemoveListener(SliderChanged);
m_Slider.value = newValue;
m_Slider.onValueChanged.AddListener(SliderChanged);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5a5524c997ae7af4780b0aaa31b8ccc7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,89 @@
using UnityEngine;
using Unity.Netcode;
using UnityEngine.UI;
namespace XRMultiplayer
{
/// <summary>
/// Simple implementation of a Networked Toggle.
/// </summary>
[RequireComponent(typeof(Toggle))]
public class NetworkedToggle : NetworkBehaviour
{
[SerializeField, Tooltip("Broadcast the value of the dropdown to all clients when a new client joins.")]
bool m_BroadcastValueOnJoin = false;
/// <summary>
/// Networked variable to sync the state of the toggle on new clients joining.
/// </summary>
NetworkVariable<bool> m_NetworkToggleValue;
/// <summary>
/// Toggle associated with this component.
/// </summary>
Toggle m_Toggle;
///<inheritdoc/>
private void Awake()
{
m_Toggle = GetComponent<Toggle>();
m_NetworkToggleValue = new NetworkVariable<bool>(m_Toggle.isOn, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
m_Toggle.onValueChanged.AddListener(UpdateToggleValue);
}
///<inheritdoc/>
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (m_BroadcastValueOnJoin)
{
// Sync the value of the dropdown.
m_Toggle.isOn = m_NetworkToggleValue.Value;
}
else
{
m_Toggle.SetIsOnWithoutNotify(m_NetworkToggleValue.Value);
}
}
/// <summary>
/// Called when the Toggle is updated by the local user.
/// </summary>
/// <param name="value">Value of the toggle.</param>
void UpdateToggleValue(bool value)
{
UpdateToggleServerRpc(value, NetworkManager.Singleton.LocalClientId);
}
/// <summary>
/// Called from the local user to the Server when the local user has updated the toggle.
/// </summary>
/// <param name="value">Value of the toggle.</param>
/// <param name="clientId">Local user Id.</param>
[ServerRpc(RequireOwnership = false)]
void UpdateToggleServerRpc(bool value, ulong clientId)
{
UpdateToggleClientRpc(value, clientId);
}
/// <summary>
/// Called from the Server on all clients when a local user has updated the toggle.
/// </summary>
/// <param name="value">Value of the toggle.</param>
/// <param name="clientId">Local user Id.</param>
[ClientRpc]
void UpdateToggleClientRpc(bool value, ulong clientId)
{
// Don't update on the local client if they sent the call.
if (NetworkManager.Singleton.LocalClientId != clientId)
{
m_Toggle.onValueChanged.RemoveListener(UpdateToggleValue);
m_Toggle.isOn = value;
m_Toggle.onValueChanged.AddListener(UpdateToggleValue);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3673f01027db6384abcf3934934e5a4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: