Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.15k stars 435 forks source link

PlayerPrefab is null after defining PlayerPrefabHash #3032

Closed devfox-se closed 2 months ago

devfox-se commented 3 months ago

Hi

I have a custom player prefabs where each client sends a payload of the prefab he had chosen to play with, the server has Connection Approval enabled and from there I successfully decode the data and find the appropriate prefab that should be attached to the player

The problem I am facing comes short after callback finishes execution

Specifically, issue is on this line as PlayerPrefab is null for some reason

https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/blob/develop/com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs#L741

The prefab has NetworkObject attached to it and its in Network Prefabs List

See my approval callback and how I grab the PlayerPrefabHash from my prefab

    private void ConnectionApproval(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
    {
        response.Approved = true;
        response.CreatePlayerObject = true;

        int clientOperatorType;

        try
        {
            clientOperatorType = System.BitConverter.ToInt32(request.Payload);
        }
        catch (System.Exception)
        {
            response.Approved = false;
            response.Reason = "Could not resolve OperatorType parameter.";
            return;
        }

        foreach (var data in OperatorPrefabsData.operatorPrefabPairs)
        {
            if ((int)data.operatorType == clientOperatorType)
            {
                NetworkObject netObject = data.prefab.GetComponent<NetworkObject>();
                response.PlayerPrefabHash = netObject.PrefabIdHash;
                Debug.Log(response.PlayerPrefabHash);
                break;
            }
        }

        if (response.PlayerPrefabHash == 0)
        {
            response.Approved = false;
            response.Reason = $"Could not find OperatorType {clientOperatorType}";
        }
        else
        {
            SetClientOperatorType(request.ClientNetworkId, clientOperatorType);
        }

        if (!response.Approved)
        {
            Debug.LogError($"Connection request from {request.ClientNetworkId} denied: {response.Reason}");
        }
    }

In the console I can see that response.PlayerPrefabHash is populated properly but the package fails to set the playerprefab after all.

Please advice what can be the issue in here? Tested on both 1.8.1 and 1.11.0

ezoray commented 3 months ago

There's a requirement even if all players are specifying their own prefab hashes that the NetworkManager's Player Prefab field be set with a prefab value. I always thought this a bug, maybe we'll get some clarification on this.

NoelStephensUnity commented 2 months ago

@ezoray @devfox-se Yeah that is indeed a bug and shouldn't be checking something that could potentially be null. I will get something together and merged by early next week (it is a simple fix and should be a relatively easy integration test to validate). Until then, I would recommend just putting a "dummy" prefab on the NetworkManage.NetworkConfig.PlayerPrefab to avoid that issue.