Justin Hirsch
Justin Hirsch

Reputation: 319

How to use multiple player prefabs for Unity's new UNET?

Has anyone got multiple player prefabs working (eg different character classes with different prefabs) on the new Unity UNET Networking?

Upvotes: 4

Views: 12747

Answers (2)

Justin Hirsch
Justin Hirsch

Reputation: 319

Finally got it working! Massive thank you to @ClausKleber for their answer at http://forum.unity3d.com/threads/how-to-set-individual-playerprefab-form-client-in-the-networkmanger.348337/#post-2256378

Edited working version below, Works with the Network Manager HUD to create and join.

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.UI;

public class NetManagerCustom : NetworkManager
{
    // in the Network Manager component, you must put your player prefabs 
    // in the Spawn Info -> Registered Spawnable Prefabs section 
    public short playerPrefabIndex;


    public override void OnStartServer()
    {
        NetworkServer.RegisterHandler(MsgTypes.PlayerPrefab, OnResponsePrefab);
        base.OnStartServer();
    }

    public override void OnClientConnect(NetworkConnection conn)
    {
        client.RegisterHandler(MsgTypes.PlayerPrefab, OnRequestPrefab);
        base.OnClientConnect(conn);
    }

    private void OnRequestPrefab(NetworkMessage netMsg)
    {
        MsgTypes.PlayerPrefabMsg msg = new MsgTypes.PlayerPrefabMsg();
        msg.controllerID = netMsg.ReadMessage<MsgTypes.PlayerPrefabMsg>().controllerID;
        msg.prefabIndex = playerPrefabIndex;
        client.Send(MsgTypes.PlayerPrefab, msg);
    }

    private void OnResponsePrefab(NetworkMessage netMsg)
    {
        MsgTypes.PlayerPrefabMsg msg = netMsg.ReadMessage<MsgTypes.PlayerPrefabMsg>();  
        playerPrefab = spawnPrefabs[msg.prefabIndex];
        base.OnServerAddPlayer(netMsg.conn, msg.controllerID);
        Debug.Log(playerPrefab.name + " spawned!");
    }

    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    {
        MsgTypes.PlayerPrefabMsg msg = new MsgTypes.PlayerPrefabMsg();
        msg.controllerID = playerControllerId;
        NetworkServer.SendToClient(conn.connectionId, MsgTypes.PlayerPrefab, msg);
    }

    // I have put a toggle UI on gameObjects called PC1 and PC2 to select two different character types.
    // on toggle, this function is called, which updates the playerPrefabIndex
    // The index will be the number from the registered spawnable prefabs that 
    // you want for your player
    public void UpdatePC ()
    {
        if (GameObject.Find("PC1").GetComponent<Toggle>().isOn)
        {
            playerPrefabIndex = 3;
        }
        else if (GameObject.Find("PC2").GetComponent<Toggle>().isOn)
        {
            playerPrefabIndex= 4;
        }
    }
}

Upvotes: 5

user3071284
user3071284

Reputation: 7100

Create a new class that derives from the built-in NetworkManager script. In there, just add a few supporting fields and an override for OnServerAddPlayer().

[SerializeField] Vector3 playerSpawnPos;
[SerializeField] GameObject character1;
[SerializeField] GameObject character2;
// etc.

GameObject chosenCharacter; // character1, character2, etc.

// Instantiate whichever character the player chose and was assigned to chosenCharacter
public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId) {

    var player = (GameObject)GameObject.Instantiate(chosenCharacter, playerSpawnPos, Quaternion.identity);
    NetworkServer.AddPlayer(conn, player, playerControllerId);

}

Reference: http://docs.unity3d.com/Manual/UNetManager.html

Upvotes: 0

Related Questions