Skip to content

Commit

Permalink
Multiplayer Beta (#774)
Browse files Browse the repository at this point in the history
* WIP UI

# Conflicts:
#	Assets/Prefabs/Panels/AdminPanel.prefab
#	Assets/Settings/Localization/Strings/Strings Shared Data.asset
#	Assets/Settings/Localization/Strings/Strings_en.asset

* Fix panel spawn

* Add MP panel to list

will probably conflict

# Conflicts:
#	Assets/Scenes/Main.unity

* Oculus connection logic for testing

* Join logic

# Conflicts:
#	Assets/Scripts/Multiplayer/MultiplayerInterfaces.cs
#	Assets/Scripts/Multiplayer/MultiplayerManager.cs

* WIP panel

* Setup new button type, fix close button

* Change instantiation point of photon runner

# Conflicts:
#	Assets/Scripts/PassthroughManager.cs

* beta tag prefab

* Add alpha tag to multiplayer

* Remove duplicate "using" block

[CI BUILD]

* Trigger CI workflow

* Minimal UI Implementation for multiplayer room

-Implemented global command: MultiplayerJoinRoom.
-Updated the multiplayer panel prefab and manager.
-Changed the admin panel layout from hexagon to octagon.
TODO:
-Add room name editing capabilities.

* Numeric keyboard popup for multiplayer room

* Buttons were too close to panel

* Don't init XR manager on start

* OpenXR should be the default in the editor

* Admin panel label tweaks

* Initialize keyboard with room name and refactor room name handling

- Added initialization of the keyboard with the current room name in `MultiplayerPanelButton.cs`.
- Changed `SetRoomName` to a property (`RoomName`) in `MultiplayerPanel.cs` for better readability and encapsulation.
- Updated `SketchControlScript.cs` to use the new `RoomName` property.

* Does Room exist

-MultiplayerManager: Added DoesRoomNameExist() and updated m_RoomData for room validation.

-MultiplayerPanel: Added UpdateRoomExistenceMessage() to indicate if a room exists or will be created (added a text to the prefab)

* Update MultiplayerManager.cs

remove  'GraphView'

* Remove graphview reference

* dotnet format

* Add Disconnection Handling for Multiplayer Mode Update

This change set introduces event-driven handling for multiplayer disconnections and ensures that the MultiplayerPanel properly updates its UI when a disconnection occurs.

* Add Leave Room button

Add Leave Room button
Add Leave Room Global Command

* Update PhotonPlayerRig.prefab

* Update MultiplayerPanel.prefab

* Editor UI to test connection to the room

* Reducing payload per Stroke Chunk

- Reducing payload per Stroke Chunk from 128 control points to 10 control points
- Adding a single point where the payload can be edited called NetworkingConstants
this is then used both in PhotonStructs.cs and PhotonManager.cs

* update Build GitHub Actions workflow (build.yml) to use the new photon tag.

* Update PopUpWindow_NumericKeyboard.prefab

aligning the collider

* Include Photon Fusion project-specific assets in version control

* Include NetworkPrefabAssetCollection.asset in version control

* Update PhotonPlayerRig.prefab

* removing the NetworkPrefbAssetCollection

* Track PhotonAppSettings

* Rebake PhotonPlayerRig

Rebake attempt

* Update SketchControlsScript.cs

1- Adding blank commands to avoid Unrecognized command Error

* Update MultiplayerPanel.cs

Multiplayer Panel
1 - Handle the Case When MultiplayerManager.m_Instance is null
2 - Avoid Accessing MultiplayerManager.m_Instance in Field Initializers

* Handle the removal of the player rig when leaving the room

handle the removal of the player rig to ensure proper Clean-up

* Update PhotonManager.cs

removing UnityEditor.Localization.Platform.Android

* Update SketchControlsScript.cs

pass pre-commit

* Create NetworkPrefabAssetCollection.asset

Adding this to solve the

* Update build.yml

predefine FUSION_WEAVER if env.PHOTON_PAT

* Fix reconnection issue by re-initializing NetworkRunner after shutdown

- Modified Disconnect() to set m_Runner to null after calling Shutdown() and destroy its GameObject to ensure proper cleanup.
- Updated Connect() to check if m_Runner is null and re-initialize it if necessary before starting a new game.
- Extracted runner initialization logic into a new method InitializeRunner() to avoid code duplication and ensure consistent setup.

This resolves the error encountered when attempting to reconnect after disconnecting, as m_Runner now correctly handles its lifecycle by being re-instantiated after shutdown.

* Lock panels to beginner mode when a user enters a multiplayer room

To block the ability to join a multiplayer session when in advance mode: I've changed the availability of the Globalcommand.MultiplayerJoinRoom to only be available when the user is beginner mode.  As part of this I also changed the MultiplayerPanel.Prefab button (join room) to AllowUnavailable to True. This change is also supported by a check that happens every time the multiplayer panel is open and a UI alert message explaining to switch to beginner mode.

To block the ability to switch to advance mode during a multiplayer session: I've changed the availability of the Globalcommand.AdvancedPanelsToggle in the IsCommandAvailable() essentially I check if the user is in a multiplayer room and if it is the advancePanelsToggle becomes unvalaible. As part of this I also changed the Admin panel prefab buttons (advance beginner mode) to AllowUnavailable to True.

* Update MultiplayerPanel.cs

initialize the multiplayer panel in lobby mode

* RPC Implementation of the Switch Environment Command

Implemented RPC_SwitchEnvironment using environment Guid.

* fix pre-commit yml

* fixing RPC Implementation of the Switch Environment Command

* Add Photon Voice Secrets

* Update AndroidManifest.xml

Adding microphone permissions

* Photon Voice Integration

* Update tag icosa-mirror/photon-fusion on build.yml [skip ci]

Update tag icosa-mirror/photon-fusion

* Trigger CI build

* Update list of symbols

Update list of symbols

* Update MultiplayerManager.cs

Check if PhotonVoiceManager get loaded

* Trigger CI Build

* [CI BUILD] Trigger CI Build

* Tiding Up Interface Connection Handler

* New Icons

* Updates To The Multiplayer UI

* Adding Disconnect Logic

Adding Disconnect Logic and Fixing Leave Room Logic

* Fixing logging messages

Fixing logging messages

* Add Alerts/Errors to multiplayer UI

* dos2unix

* Changes to MultiplayerManager

Fixing incorrect conditions for executing networked commands.

* more dos2unix

* Force Windows to use LF line endings for .cs and .py files

Force Windows to use LF line endings for .cs and .py files

* Update BaseCommand.cs

Adding timestamps when photon is present

* Fix the mirror for multiplayer

Fix the mirror widget  for multiplayer

The first problem is related to the fact that the current implementation of the multiplayer does not properly transmit and serialize the chain of commands especially the property of the basecommand m_Children and m_Parent.

The second problem this commit address is the fact that In mirror mode, the brush stroke command is invoked twice. Initially, a single brush stroke command is sent. The second invocation sends a command chain, including the initial brush stroke as a parent and a second mirrored stroke as its child. Sending both instances through PhotonRPC causes issues, as the first brush stroke command is received twice, leading to duplication and processing errors on the receiving peer. To resolve this  we use PerformAndRecordCommand in place of RecordCommand, and we change the PointerManager.FinalizeLine(), PointerScript.DetachLine(), SketchMemoryScript.MemorizeBatchedBrushStroke() to utilize a parameter

* Fix Check if Room Exist

Fix on MultiplayerManager.cs

and extend the range of checks on MultiplayerPannel.cs

* Room Owner

Update Photon Manager with a GetPlayerCount() method used to establish if a user is a room owner

Update Multiplayer Manager with a isUserRoomOwner

* Implement basic history synchronization

Upon a remote player joining, the room owner now transmits all commands in the operation stack, ensuring the new player receives the complete command history for a consistent session state.

* Clear scene for non-room owner players on join

Clear scene for non-room owner players on join: If a player joins and is not the room owner, their scene is reset to ensure consistency with the room owner's state upon receiving the synchronized history.

* Improving Remote Player Registration

Remote players were not correctly registered when already present in the room because `INetworkRunnerCallbacks.OnPlayerJoined` in Fusion 1 is not called for users who are already in the room.

To address this, we added and registered existing users using the `CheckExistingUsers()` method.

Additionally, in `MultiplayerManager.cs`, the local player ID was not registered correctly, which has now been fixed.

A display for both the local and remote user IDs was added to `MultiplayerManagerEditor.cs` to facilitate debugging.

* Fix Remote User List Clearing

Fixed issue where remote user list was not cleared on disconnect or room exit.

* Update MultiplayerManagerEditor.cs

 Enhanced MultiplayerManager Editor to streamline debugging with clearer information display and controls.

* Introduce coroutine for sending command history via Photon network

This update refactors `SendCommandHistory` to use a coroutine, sending commands in batches with a delay between each batch. This approach reduces the likelihood of Photon RPC message delivery failures that occur when too many messages are sent within the same frame. The coroutine yields between batches and includes a configurable delay to ensure smooth, reliable transmission over the network.

* GUIDs check and consistency between peers

Add support for initializing commands with existing GUIDs

Check memory script stack for guid commands before performing the command

* Networking isRoomOwner

To correctly define who is the room owner beyond the two users case we need to share this property, we do this by extending the PhotonPlayerRig NetworkBehaviour component

* Room Ownership logic updated

* Room Ownership logic updated

* Room Ownership logic updated

Taking care of few edge cases and cleaning logs

* Headset scale  added to player rig

* Controllers Added to the player rig

* Set Undo and Redo unavailable while connected

* Updating Connect and Disconnect Logic in the UI

Removing the Connect and Disconnect buttons and extending the MultiplayerPanel.cs to connect when enabled. If the user is not in the room, it will disconnect when disabled.

* Display Room Ownership on the UI

Added a RoomOwnershipUpdated action to MultiplayerManager.cs to send updates about room ownership to the multiplayer UI panel. Updated the MultiplayerPanel script and prefab to include a Room Ownership field.

* Fix display of room Ownership

* Fix null reference issues in PhotonPlayerRig

Fix null reference issues in PhotonPlayerRig by adding checks for destroyed objects in RecieveData and other methods.

* Fix invalid localScale assignment due to extreme SceneScale values

Clamped SceneScale to prevent division by zero or extremely small values.

* Updating UI command descriptions for Multiplayer UI

Updating the languages translations for the Multiplayer UI

* Resolve Controller Flickering

 Updated the PhotonPlayerRig prefab to properly manage dummy transforms and model transforms for left/right controllers.

* Update MultiplayerManager.cs

removing redundant commented code

* Prevent Access to Networked Properties After PhotonPlayerRig Despawns

- Introduced m_IsSpawned flag in PhotonPlayerRig to track spawn state.
- Updated ReceiveData() to check m_IsSpawned before accessing IsRoomOwner, avoiding InvalidOperationException.
- Set m_IsSpawned to false in OnDestroy() to handle object despawning.
- Added warning logs for attempts to access networked properties post-despawn, aiding in debugging.

* RecieveData to ReceiveData

* Disable Undo/Redo in Multiplayer specifically Controller buttons

Extended CanRedo() and CanUndo() methods in SketchControlScript to include a condition checking if the connection state is IN_ROOM, preventing undo/redo functionality when in multiplayer mode.

* Disable loading sketches when in multiplayer mode

* hiding extra button on prefab

* [CI BUILD]

* Removing m_GuidCache

Removing unused m_GuidCache

* Separation of Command Stacks

Divided local (m_OperationStack) and network (m_NetworkStack) command stacks to handle independent undo/redo flows for local and networked operations.
Added IsCommandInNetworkStack to check for repeated commands in the network stack, ensuring no duplicate processing.
Facilitates clearer distinction between local and global operations in multiplayer scenarios.

* Update to SendCommandHistory() to include the network command stack

* Introduce networked timestamps for commands

This ensures that command histories across different stacks can be transmitted and synchronized in order between peers.

* Clear NetworkStack in ClearMemory() to prevent command reception issues after multiplayer sessions

When calling ClearMemory(), the NetworkStack must be cleared alongside other stacks. Without this, IsCommandInStack may find existing GUIDs in NetworkStack, causing new commands to be ignored after entering and exiting multiplayer rooms. Clearing NetworkStack ensures that old command GUIDs don't interfere with new commands, allowing them to be received and processed correctly.

* Update BaseCommand.cs

wrongly referencing Fusion

* Updating to Room Owner Logic

* Implementing Reference StrokeData to BrushStrokeCommands

Implementing WeakReference between Strokes and BrushStrokeComma.
This allows the garbage collector to collect the BrushStrokeCommand if it's no longer in use elsewhere.

* Identify Command-less Strokes

We have implemented the GetStrokesWithoutCommand() method in SketchMemoryScript.cs. This enhancement enables us to distinguish between strokes in the memory list that were loaded from deserialization (i.e., from a file) and those that were interactively generated during the current session. By identifying strokes without referenced brush stroke command, we can better understand the origin of each stroke and manage them accordingly.

* Implementing command-less Strokes Synchronization

The newly implemented GetStrokesWithoutCommand() function in SketchMemoryScript.cs significantly improves stroke synchronization. This function not only retrieves all commands from the various stacks but also identifies strokes that lack associated commands—specifically, those that have been deserialized or loaded from files. By distinguishing these command-less strokes, we can effectively share them with peers, avoiding redundances.

* Implement Estimation of Command-to-Network-Message Conversion

Some commands must be split into multiple network messages due to payload size limitations per message. In this changeset, we implemented a function to estimate the number of network messages required to transmit each command. This enhancement improves the efficiency of the coroutine responsible for synchronizing the scene with new users.

* Reducing log level for pun fusion and voice

* Limiting sequential execution of the SendStrokesAndCommandHistory coroutine to one queued instance

Overlapping coroutines could result in network packet loss and cause users to receive an incomplete scene. This commit prevents overlapping execution of SendStrokesAndCommandHistory by allowing only one active coroutine and one queued instance. This ensures that users joining during an ongoing or queued execution receive a complete history of commands.

* Test reliable for brush commands

* Disable edit room and nickname buttons when in room

Disable edit room and nickname buttons when in room

* Add a button to erase all text

Add a button to the keyboard pop up to erase all text

* Implementing Sync Information for Users Joining Multiplayers Room

Added synchronization info display when a user(non owners) joins the room.
Updates synchronization percentage dynamically.
Clears sync info upon completion.

* Implement Environment Synchronization for Sketch-Loaded Environments

SendStrokesAndCommandHistory  lack environment updates loaded from files. This change ensures environments loaded from sketches are synchronized, improving scene consistency.

* Move History Synchronization Logic to his own class

* Update HistorySynchronizationManager.cs

Add a list of users being update to manage the display updates for each

* Update PhotonRPC.cs

Add an optional target player to RPC methods to enable one-to-one  history synchronization rather than one-to-many

* Implement Acknowledgment-Based History Synchronization to Ensure Reliability [skip ci]

Data packets continue to be lost during history synchronization, even with reliable transmission and controlled packet rates. To address this, we are transitioning to a system where every synchronization command is explicitly acknowledged by the receiving user, ensuring robust and reliable synchronization.

* Switching to Photon Fusion 2 [skip ci]

* Implementing Large Data Streaming [skip ci]

Leveraging Fusion 2 to transmit the latest autosaved data.

* Update build.yml

update with new symbol FUSION2
and new tag Fusion_v2_Voice_2 for icosa-mirror/photon-fusion

* Update UnityGLTFSettings.asset

* Fix formatting in Multiplayer defines

* Update PhotonManager.cs

CheckExistingUsers() is no longer needed because OnPlayerJoined behaves differently in Fusion 2 compared to Fusion 1.

Additionally, PlayerRef can no longer be generated directly from the playerId. Instead, a method (PlayerRef .FromEncoded()) must be used to generate them, therefore we no longer store the  PlayerRef.playerId instead we store the  PlayerRef .RawEncoded value.

* Multiplayer Stroke Serialization

new class which provides a methods to Serializes a LinkedList of Strokes into a byte array and deserialize them in order to use the m_Runner.SendReliableData

* Multiplayer Scene Sync

Renaming History Synchronization manager to Multiplayer Scene Sync
Migrating the code for sending large bytes from the multiplayer manager to the Multiplayer Scene Sync
implementing the choice to sync the scene with commands (old method) or by sharing strokes (new reliable  method)

* Implement  display of progress for stroke synchronization

1 - implement strokes guid
2 - Implement  display of progress for stroke synchronization

* Change Label on menu alpha->beta

Commented some debug messages

* Implement  failsafe logic for GenerateUniqueRoomName

We limit the attempts to 10

* Hide nickname

* Update MultiplayerPanel.cs

Updating phrases

"Switch to beginner mode to Join Room" -> "Switch to Beginner Mode to use Multiplayer"
"You are Room Owner" -> "You are the Room Owner"
"You are Not Room Owner" -> "You are not the Room Owner"
"$"The room {data.roomName} already exist your joining an existing session." -> "$"Room {data.roomName} already exists. You will be joining an existing session."

"/n" -> "\n"

* What's New Button On Admin Panel

Updating the localization strings for the what's new button on admin panel

* Implement avatar speaking feedback

Detect if the user is transmitting through the voice channel and display speaking feedback on the remote avatar by changing the HMD color.

* Implementing nickname display on remote avatars

* changing TAB to beta

* Simplify connection state ConnectionState.IN_ROOM -> "In Room"

* Implement PhotonRPCBatcher to Reduce Network Congestion and Ensure Reliable Command Delivery

Problem: Occasionally, commands fail to be delivered or executed, leading to inconsistencies in the scene. The issue stems from commands being sent but not received, likely due to network congestion suppressing them.

Solution: To reduce congestion, we limit the number of RPCs sent per frame by using the PhotonRPCBatcher.

* Revert unintended get_license.yml change

* Remote player controller size fix

* Synch -> Sync

* Sync not reaching 100% on display

* Nickname disappearing from panel after disconnection

* Persistent nickname

we save the nickname in the PlayerPrefsDataStore

* What's New" button string overwritten Fix

* New Define -> MP_PHOTON

* Update README.md

* Missing En Description

* Fix Labs and Scripts panels

* Disable clear sketch when in multiplayer

todo -->
1. enable just for room owner
2. Create RPC comand

* Update PhotonStructs.cs

miss defined

* Update MultiplayerPanel.prefab

Beta Tag via localization

* Localization Added for Multiplayer Panel

* InitialiSing -> InitialiZing

* UnamedUser -> UnnamedUser

* Update README.md

fixes to readme

* Disable passthrough in multiplayer

* Runtime switching for experimental brushes

* Photon does not join (room full) Realtime Voice joins anyway

Photon does not join the room (room full) while Realtime Voice joins anyway

* Localization fix

* Icon experimental badges need to update all the time

* Add alert to check if passthrough environment is active

* Remove hardcoded passthrough GUID

Replaced
PASSTHROUGH_GUID = "e38af599-4575-46ff-a040-459703dbcd36";
with a new property isPassthrough in the environment scriptable object.

* Multiplayer admin menu string fix

* Disable Join Button if in PassThrough mode

* PhotonPlayerRig -> TextMeshPro -> autosize

Nickname to fit in the headset

* UnnamedUser -> Unnamed

* Sync reaching 100% and complete

* Grey out the 'What's New' button on the admin panel.

* Sync reaching 100% and complete

---------

Co-authored-by: Mike Nisbet <[email protected]>
Co-authored-by: Mike Nisbet <[email protected]>
Co-authored-by: Riccardo Bovo <[email protected]>
Co-authored-by: Mike Miller <[email protected]>
Co-authored-by: Riccardo Bovo <[email protected]>
  • Loading branch information
6 people authored Dec 21, 2024
1 parent 22a22a2 commit d5384b0
Show file tree
Hide file tree
Showing 103 changed files with 16,475 additions and 1,666 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ jobs:
with:
token: ${{ env.PHOTON_PAT }}
repository: icosa-mirror/photon-fusion
ref: v1.1.8
ref: Fusion_v2_Voice_2
path: photon-fusion-mirror/

- name: Copy photon files
Expand Down Expand Up @@ -449,6 +449,11 @@ jobs:
run: |
sed -e 's/androidUseCustomKeystore.*$/androidUseCustomKeystore: 1/' -i ProjectSettings/ProjectSettings.asset
- name: Add PHOTON_PAT specific define
if: ${{ env.PHOTON_PAT }}
run: |
echo -e "\n -define:MP_PHOTON \n -define:PHOTON_UNITY_NETWORKING \n-define:PUN_2_0_OR_NEWER \n-define:PUN_2_OR_NEWER \n-define:PUN_2_19_OR_NEWER \n-define:FUSION_WEAVER \n-define:FUSION2 \n-define:CROSS_PLATFORM_INPUT \n-define:MOBILE_INPUT \n-define:PHOTON_VOICE_DEFINED" | tee -a Assets/csc.rsp
- name: Update build matrix specific defines in csc.rsp
if: ${{ matrix.extra_defines }}
run: |
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ Packages/com.unity.xr.picoxr
/Assets/Photon/**
/Assets/Photon.meta
!/Assets/Photon/Fusion/Resources/NetworkProjectConfig.fusion*
!/Assets/Photon/Fusion/Resources/PhotonAppSettings.asset*
!/Assets/Photon/Fusion/User/NetworkPrefabAssetCollection.asset*

# Cache files
*.cache
4 changes: 2 additions & 2 deletions Assets/Editor/BuildTiltBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1435,7 +1435,7 @@ static void ShowBrushExportTextures()
using (var unused = new TempHookUpSingletons())
{
// Set consultUserConfig = false to keep user config from affecting the build output.
TiltBrushManifest manifest = App.Instance.GetMergedManifest(forceExperimental: true);
TiltBrushManifest manifest = App.Instance.ManifestFull;

StringBuilder s = new StringBuilder();
foreach (BrushDescriptor desc in manifest.UniqueBrushes())
Expand Down Expand Up @@ -1547,7 +1547,7 @@ public static void DoBuild(TiltBuildOptions tiltOptions)
// to be run at build-time (ie when nobody has called Start(), Awake()).
// TempHookupSingletons() has done just enough initialization to make it happy.
// Also set consultUserConfig = false to keep user config from affecting the build output.
TiltBrushManifest manifest = App.Instance.GetMergedManifest(forceExperimental: true);
TiltBrushManifest manifest = App.Instance.ManifestFull;

// Some sanity checks
{
Expand Down
189 changes: 189 additions & 0 deletions Assets/Editor/MultiplayerManagerEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// MultiplayerManagerInspector.cs
using UnityEditor;
using UnityEngine;
using OpenBrush.Multiplayer;
using System.Threading.Tasks;
using System.ComponentModel.Composition;

#if UNITY_EDITOR
[CustomEditor(typeof(MultiplayerManager))]
public class MultiplayerManagerInspector : Editor
{
private MultiplayerManager multiplayerManager;
private string roomName = "1234";
private bool isPrivate = false;
private int maxPlayers = 4;
private bool voiceDisabled = false;

public override void OnInspectorGUI()
{
multiplayerManager = (MultiplayerManager)target;

DrawDefaultInspector();

GUILayout.Space(10);
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
GUILayout.Space(10);

roomName = EditorGUILayout.TextField("Room Name", roomName);

//State
string connectionState = "";
if (multiplayerManager != null) connectionState = multiplayerManager.State.ToString();
else connectionState = "Not Assigned";

GUILayout.Space(10);
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Connection State: ", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"{connectionState}");
EditorGUILayout.EndHorizontal();
GUILayout.Space(5);

if (GUILayout.Button("Connect"))
{
ConnectToLobby();
EditorUtility.SetDirty(target);
}


if (GUILayout.Button("Join Room"))
{
ConnectToRoom();
EditorUtility.SetDirty(target);
}


if (GUILayout.Button("Exit Room"))
{
DisconnectFromRoom();
EditorUtility.SetDirty(target);
}


if (GUILayout.Button("Disconnect"))
{
Disconnect();
EditorUtility.SetDirty(target);
}

if (GUILayout.Button("Refresh Room List"))
{
CheckIfRoomExists();
EditorUtility.SetDirty(target);
}

//Local Player Id
string localPlayerId = "";
if (multiplayerManager.m_LocalPlayer != null) localPlayerId = multiplayerManager.m_LocalPlayer.PlayerId.ToString();
else localPlayerId = "Not Assigned";

GUILayout.Space(10);
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Local Player ID: ", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"{localPlayerId}");
EditorGUILayout.EndHorizontal();

//Room Ownership
string ownership = "";
if (multiplayerManager != null && multiplayerManager.IsUserRoomOwner()) ownership = "Yes";
else if (multiplayerManager != null && !multiplayerManager.IsUserRoomOwner()) ownership = "No";
else ownership = "Not Assigned";

EditorGUILayout.BeginHorizontal();
GUILayout.Label("Is Local Player Room Owner:", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"{ownership}");
EditorGUILayout.EndHorizontal();

//Remote Users
string remoteUsersRegistered = "";
if (multiplayerManager.m_RemotePlayers != null && multiplayerManager.m_RemotePlayers.Count > 0)
{
remoteUsersRegistered = "UserIds:[ ";
foreach (var remotePlayer in multiplayerManager.m_RemotePlayers)
{
remoteUsersRegistered += remotePlayer.PlayerId.ToString() + ",";
}
remoteUsersRegistered += "]";
}
else remoteUsersRegistered = "Not Assigned";

//Registered remote players

EditorGUILayout.BeginHorizontal();
GUILayout.Label("Registered Remote Players IDs:", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"{remoteUsersRegistered}");
EditorGUILayout.EndHorizontal();

// Display and edit Nickname
GUILayout.Space(10);
EditorGUILayout.LabelField("Nickname", GUI.skin.horizontalSlider);
string currentNickname = multiplayerManager.UserInfo.Nickname;
GUILayout.Label("Nickname", EditorStyles.boldLabel);
string newNickname = EditorGUILayout.TextField("Edit Nickname", currentNickname);
if (newNickname != currentNickname)
{
ConnectionUserInfo updatedUserInfo = multiplayerManager.UserInfo;
updatedUserInfo.Nickname = newNickname;
multiplayerManager.UserInfo = updatedUserInfo;
EditorUtility.SetDirty(target); // Mark the target as dirty to apply changes
}


Repaint();

}

private async void ConnectToLobby()
{
if (multiplayerManager != null)
{
bool success = await multiplayerManager.Connect();
}
}

private async void ConnectToRoom()
{
if (multiplayerManager != null)
{
RoomCreateData roomData = new RoomCreateData
{
roomName = roomName,
@private = isPrivate,
maxPlayers = maxPlayers,
voiceDisabled = voiceDisabled
};

bool success = await multiplayerManager.JoinRoom(roomData);

}
}

private async void DisconnectFromRoom()
{
if (multiplayerManager != null)
{
bool success = await multiplayerManager.LeaveRoom();

}
}

private async void Disconnect()
{
if (multiplayerManager != null)
{
bool success = await multiplayerManager.Disconnect();

}
}

private void CheckIfRoomExists()
{
if (multiplayerManager != null)
{
bool roomExists = multiplayerManager.DoesRoomNameExist(roomName);
}
}
}
#endif
11 changes: 11 additions & 0 deletions Assets/Editor/MultiplayerManagerEditor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 10 additions & 2 deletions Assets/OculusMR/OculusMRController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,19 @@ public async void StartMRExperience(bool isHosting)
{
await m_SpatialAnchorManager.CreateSpatialAnchor();
m_SpatialAnchorManager.SceneLocalizeToAnchor();
MultiplayerManager.m_Instance.Connect();
MultiplayerManager.m_Instance.JoinRoom(new RoomCreateData()
{
roomName = "OculusMRRoom",
maxPlayers = 12
});
}
else
{
MultiplayerManager.m_Instance.Connect();
MultiplayerManager.m_Instance.JoinRoom(new RoomCreateData()
{
roomName = "OculusMRRoom",
maxPlayers = 12
});
}
}

Expand Down
Loading

0 comments on commit d5384b0

Please sign in to comment.