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,49 @@
using UnityEngine;
using TMPro;
namespace XRMultiplayer
{
/// <summary>
/// Represents a message text on a message board.
/// </summary>
public class MessageText : MonoBehaviour
{
/// <summary>
/// The text component to display the message.
/// </summary>
[SerializeField] private TMP_Text text;
/// <summary>
/// The text component to display the time.
/// </summary>
[SerializeField] private TMP_Text timeText;
/// <summary>
/// Use this value for any headers or offsets that need to be added to the message text when calculating height.
/// </summary>
[SerializeField, Tooltip("Use this value for any headers or offsets that need to be added to the message text when calculating height.")]
float m_BonusScale = 1.0f;
[SerializeField] RectTransform m_RectTransform;
/// <summary>
/// Sets the message and time to be displayed.
/// </summary>
/// <param name="message">The message to be displayed.</param>
/// <param name="time">The time to be displayed.</param>
public void SetMessage(string message, string time)
{
text.SetText(message);
timeText.SetText(time);
Canvas.ForceUpdateCanvases();
SnapHeight();
}
[ContextMenu("Snap Height")]
void SnapHeight()
{
m_RectTransform.sizeDelta = new Vector2(m_RectTransform.sizeDelta.x, text.preferredHeight * m_BonusScale /* * text.fontSize*/);
Canvas.ForceUpdateCanvases();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2bc4ec75d1dc40c4e8da2c62f9789aff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,173 @@
using UnityEngine;
using Unity.Netcode;
using Unity.Collections;
using System;
using UnityEngine.XR.Interaction.Toolkit.Samples.SpatialKeyboard;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace XRMultiplayer
{
/// <summary>
/// Represents a message board that allows players to submit and display messages in a networked environment.
/// </summary>
public class NetworkMessageBoard : NetworkBehaviour
{
/// <summary>
/// The prefab for the message text.
/// </summary>
[SerializeField] GameObject m_MessagePrefab;
/// <summary>
/// The transform that contains the viewport for the messages.
/// </summary>
[SerializeField] Transform m_ContentViewport;
/// <summary>
/// The maximum number of messages that can be displayed.
/// </summary>
[SerializeField] int m_MaxMessageCount = 100;
/// <summary>
/// The maximum number of characters that can be displayed in a message.
/// </summary>
[SerializeField] int m_MaxCharacterCount = 256;
/// <summary>
/// The list of current messages.
/// </summary>
NetworkList<FixedString512Bytes> messageList;
/// <inheritdoc/>
void Start()
{
XRINetworkGameManager.Connected.Subscribe(ConnectedToNetwork);
messageList = new NetworkList<FixedString512Bytes>(default, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
}
/// <summary>
/// Called when the network connection status changes.
/// </summary>
/// <param name="connected">Indicates whether the player is connected to the network.</param>
void ConnectedToNetwork(bool connected)
{
if (!connected)
{
foreach (Transform t in m_ContentViewport)
{
Destroy(t.gameObject);
}
}
}
// Called from XRIKeyboardDisplay
public void ToggleKeyboardOpen(bool toggle)
{
GlobalNonNativeKeyboard.instance.keyboard.closeOnSubmit = !toggle;
}
/// <inheritdoc/>
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (IsServer)
{
messageList.Clear();
}
foreach (FixedString512Bytes message in messageList)
{
CreateText(message.ToString());
}
}
/// <summary>
/// Submits a text message locally.
/// </summary>
/// <param name="text">The text message to submit.</param>
public void SubmitTextLocal(string text)
{
if (string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text)) return;
string textToSend = $"<b>{XRINetworkPlayer.LocalPlayer.playerName}</b>:<br><br>{text}";
if (textToSend.Length > m_MaxCharacterCount)
{
textToSend = textToSend.Substring(0, m_MaxCharacterCount);
}
FixedString512Bytes newText = new FixedString512Bytes(textToSend);
SubmitMessageServerRpc(newText);
}
/// <summary>
/// Submits a message to the server.
/// </summary>
/// <param name="text">The message to submit.</param>
[ServerRpc(RequireOwnership = false)]
void SubmitMessageServerRpc(FixedString512Bytes text)
{
messageList.Add(text);
if (messageList.Count > m_MaxMessageCount)
{
messageList.RemoveAt(0);
}
SubmitMessageClientRpc(text);
}
/// <summary>
/// Submits a message to the clients.
/// </summary>
/// <param name="text">The message to submit.</param>
[ClientRpc]
void SubmitMessageClientRpc(FixedString512Bytes text)
{
CreateText(text.ToString());
}
/// <summary>
/// Creates a text message and adds it to the message board.
/// </summary>
/// <param name="text">The text of the message.</param>
void CreateText(string text)
{
Instantiate(m_MessagePrefab, m_ContentViewport).GetComponent<MessageText>().SetMessage(text, DateTime.Now.ToString("h:mm tt"));
// message.SetMessage(text, DateTime.Now.ToString("h:mm tt"));
if (m_ContentViewport.childCount > m_MaxMessageCount)
{
Destroy(m_ContentViewport.GetChild(0).gameObject);
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(NetworkMessageBoard), true), CanEditMultipleObjects]
public class NetworkMessageBoardEditor : Editor
{
[SerializeField, TextArea(10, 15)] string m_DebugText;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
GUILayout.Space(10);
GUILayout.Label("Debug Area", EditorStyles.boldLabel);
GUI.enabled = XRINetworkGameManager.Connected.Value;
if(!XRINetworkGameManager.Connected.Value)
{
GUILayout.Label("Connect to a network to submit messages.", EditorStyles.helpBox);
}
else
{
GUILayout.Label("Debug Text");
m_DebugText = GUILayout.TextArea(m_DebugText);
}
if (GUILayout.Button("Submit Text Debug"))
{
((NetworkMessageBoard)target).SubmitTextLocal(m_DebugText);
}
GUI.enabled = true;
}
}
#endif
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0ec9afa5a52ab1f49ba7d6429da6a00d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: