Migrating from Unity Netcode for GameObjects to Coherence

I want to try and migrate from a project that use Unity Netcode for GameObject to Coherence.
I couldn’t find one place with all the relevant info and tips, so I hope this post would help not just me.

I want to focus on using existing architecture, with minimal changes. While re-writing everything from scratch might be better architecture wise, I don’t find it much practical for this scope.

The project I’m working on is this: GitHub - De-Panther/webxr-multiplayer-template: Unity WebXR Multiplayer Template, based on Unity VR Multiplayer Template.

It has Lobby system (with Relay and Transport).
The Host is one of the Clients, and there’s yet no implementation of server hosting or transferring the Host role.
There are some shared 3D menus and mini-games.

So far I imported Coherence package version 1.3.1. And added the Bridge and Query objects to the scene.

The first prefab I tried to migrate is the player prefab, as I think it is one of the more complicated ones.
It has 2 NetworkBehaviour classes. XRINetworkPlayer and XRHandPoseReplicator.

I removed the NetworkObject component from the prefab, and added CoherenceSync component instead.

I replaced NetworkBehaviour with MonoBehaviour in both classes and added a reference to the CoherenceSync.

And here comes the troubles :slight_smile:

The project is heavily relay on the NetworkBehaviour properties.
IsOwner is now based on coherenceSync.HasStateAuthority.
IsLocalPlayer is also based on coherenceSync.HasStateAuthority but I’m not sure if there’s a more precise property.
IsOwnedByServer in this case is used to check if it’s the host, I don’t know what to use here for now. Any suggestions?
OwnerClientId is ulong but maybe using the string coherenceSync.EntityState.CoherenceUUID would work for the use cases in this project. Is it correct to use CoherenceUUID of a player prefab to identify client?

Next are NetworkVariable and NetworkList.
The CoherenceSync component creates a scheme from selected public variables, and let us sync them.
The NetworkVariable is similar to such variables, but it also allows to Subscribe and Unsubscribe for when the value changed. I tried to find a way to subscribe to CoherenceSync variables events, but found only Rigidbody related ones. Are there events for custom variables as well?
I couldn’t find similar solution to sync lists like the NetworkList does. What would you suggest to sync lists of float and of vector3? (no need to subscribe for changes)

Project question:
While Coherence has Lobby system, I think the way this Unity project was made, it’s better to use only the Rooms system as players are still in the same room while in the mini-games. Any suggestions on how to handle the Host role and transferring it when the host disconnects? (Using the Rooms system)

Thanks :slight_smile:

Yes, coherence has dynamic authority, so in your case where you are not using a simulator (I assume you are not?) then IsOwnedByServer is the same as HasStateAuthority.

Checkout out Client Connections: Client Connections | coherence Documentation

This will allow you to have a guaranteed ClientID (which can also be cast to ulong) provided by coherence. That client ID is guaranteed to remain stable as long as the connection is stable.

Yes, take a look at OnValueSynced [OnValueSynced] Attribute | coherence Documentation

List sync is high on our priority list - don’t have a timeframe right now - but our recommendation is to serialize the list into a byte array. You can either make this a normal sync property that gets set when the list changes, or you can use Commands to send changes depending on your use case.

Since authority is dynamic in our system you can rely on persistent entities and orphan handling to transfer or Adopt network entities when the owner of them changes: Authority | coherence Documentation

In a traditional host scenario, if your host truly has authority over all network entities, you can make them “persistent” (meaning this will stay in the room when the host leaves) and then devise an adoption scheme that you’d like.

2 Likes

Thanks for the help!

Some progress updates:

  • Managed to configure most of the player properties and mechanics.
  • Can log in using the Sample Connect Dialog for Rooms.
  • Managed to sync some of the lists, but it’s not optimal.
  • For now selecting a host is not an issue, the experience can work without it.
  • Baking the scheme, and using the CoherenceSyncConfig of the player prefab to instantiate it from the bridge saved me some time.
  • Had to cache the HasStateAuthority and ClientId on Start() as when OnDestroy() is called, they change. I guess I can subscribe to state authority changed.
  • Had to use int instead of enum for enums that needed sync.

Following previous comment:

  • IsOwnedByServer - I’ll skip for now. Using HasStateAuthority is not the same, and in the context of this experience, it doesn’t have much importance. I set it to always return false.
  • Thanks for the tip. coherenceSync.EntityState.ClientConnection.ClientId.GetHashCode() did the trick.
  • OnValueSynced worked great. It’s not the same one to one, but close enough.
  • I managed to use byte array, but it forces me to set it as new byte[] each frame that I want to update it. So I’m looking for another solution.

Current issues:

  • There are 2 float arrays and 2 Vector3 arrays the I know the size of only when player joins. They don’t change size when connected. In some cases all their items updates each frame, and in some cases only few or none. They are used for fingers joints rotations and fingers states. I read about sync and commands, but I’m not sure what would work better and how for this case.
  • Netcode for GameObjects has NetworkTransform component, that can sync child transforms of NetworkObject. I ended up adding a bunch of Vector3 and Quaternion to sync a few child transforms. Couldn’t find a quick option for that. Is there an equivalent for NetworkTransform?

Thanks