How to get prefab hash ?

Hello there,

I’m trying to use the ConnectionApproval feature to choose which prefab to spawn for my client as a PlayerObject.

In the documentation (https://docs-multiplayer.unity3d.com/docs/getting-started/connection-approval), it is said that the ConnectionApprovalCallback can take as parameter the hash of the prefab to use as the player object.

Here is the example code of ApprovalCheck in the documentation:

private void ApprovalCheck(byte[] connectionData, ulong clientId, MLAPI.NetworkManager.ConnectionApprovedDelegate callback)
{
    //Your logic here
    bool approve = true;
    bool createPlayerObject = true;

    // The prefab hash. Use null to use the default player prefab
    // If using this hash, replace "MyPrefabHashGenerator" with the name of a prefab added to the NetworkPrefabs field of your NetworkManager object in the scene
    ulong? prefabHash = NetworkSpawnManager.GetPrefabHashFromGenerator("MyPrefabHashGenerator");
  
    //If approve is true, the connection gets added. If it's false. The client gets disconnected
    callback(createPlayerObject, prefabHash, approve, positionToSpawnAt, rotationToSpawnWith);
}

I’m using Netcode for GameObjects 1.0.0-pre.6, and the problem is, in that version, NetworkSpawnManager.GetPrefabHashFromGenerator doesn’t exist anymore. It seems to me that the callback is waiting an uint corresponding to the GlobalObjectIdHash of the NetworkObject and I have no idea how to access it (everything using it seems to be internal).

I know there is a workaround, I can call the callback with createPlayerObject set to false and manage the player object spawn manually, but it’s not as clean as make the framework create it for us.

In the editor you can click Override on the prefab in NetworkManager and add your own hash value there, then use that value in the ApprovalCheck. I don’t know how you generate that hash though, I tried an arbitrary uint value and it spawned the overridden prefab.

Ohhh, ok.
That’s not very convenient. Not sure it’s the intended use as we can easily spawn a network object manually. I think the prefab Override in the NetworkManager is meant to be able to do network through different projects (have a different project for the client and the server).
I’ll stick to my workaround for now, it gives me more control and doesn’t rely on entering something specific in editor.

If you’re trying to get a hash of a GameObject that was not spawned yet:

You can use the PrefabIdHash property to get the prefab hash. Do note that it is expensive, since it iterates over every registered prefab. As an alternative, you can use the method below.

If you’re trying to get the prefab hash of an already-active GameObject:

I made an extension method for getting a hash from an already-spawned prefab:

public static class ForceGetPrefabHash
{
    public static uint GetPrefabHash(this NetworkObject obj)
    {
        return (uint)(typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj));
    }
}