Search Unity

How to get prefab hash ?

Discussion in 'Netcode for GameObjects' started by Skanou_Dev, Mar 22, 2022.

  1. Skanou_Dev

    Skanou_Dev

    Joined:
    Jun 22, 2017
    Posts:
    7
    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:
    Code (CSharp):
    1. private void ApprovalCheck(byte[] connectionData, ulong clientId, MLAPI.NetworkManager.ConnectionApprovedDelegate callback)
    2. {
    3.     //Your logic here
    4.     bool approve = true;
    5.     bool createPlayerObject = true;
    6.  
    7.     // The prefab hash. Use null to use the default player prefab
    8.     // If using this hash, replace "MyPrefabHashGenerator" with the name of a prefab added to the NetworkPrefabs field of your NetworkManager object in the scene
    9.     ulong? prefabHash = NetworkSpawnManager.GetPrefabHashFromGenerator("MyPrefabHashGenerator");
    10.  
    11.     //If approve is true, the connection gets added. If it's false. The client gets disconnected
    12.     callback(createPlayerObject, prefabHash, approve, positionToSpawnAt, rotationToSpawnWith);
    13. }
    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.
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    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.
     
  3. Skanou_Dev

    Skanou_Dev

    Joined:
    Jun 22, 2017
    Posts:
    7
    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.
     
  4. EladNLG

    EladNLG

    Joined:
    Dec 24, 2019
    Posts:
    1
    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:

    Code (CSharp):
    1. public static class ForceGetPrefabHash
    2. {
    3.     public static uint GetPrefabHash(this NetworkObject obj)
    4.     {
    5.         return (uint)(typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj));
    6.     }
    7. }