Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unity Multiplayer: How to create swappable character classes during real time multiplayer game

Discussion in 'Multiplayer' started by Oakioats, Mar 5, 2017.

  1. Oakioats

    Oakioats

    Joined:
    Mar 27, 2016
    Posts:
    7
    I am working with UNET to create a online multiplayer twisted metal sort of game. Weaponized cars attacking each other, etc. I want the player to be able to choose from an array of car prefabs to spawn as their player prefab during the match. When the player dies, they can choose a new car to switch if they want when they spawn. Its class switching between deaths.

    As of now and with some sifting around I have found no documentation on how to accomplish this. There is documentation to choose a class in the lobby manager and spawn as that character. Yet to switch the player prefab in the network manager during run time has yet to be specified.

    Anyone have any experience with this or knows someone or another game that did it with unity? None of the multiplayer examples for Unity touch base with this. Would really like to learn more. Thank you
     
  2. donnysobonny

    donnysobonny

    Joined:
    Jan 24, 2013
    Posts:
    220
    Okay so, as you've already discovered, the "player prefab" that you specify in the NetworkManager component has limited usability. In short, it's only really useful if a "player" will spawn a single object upon connection, and when that object is destroyed when the player disconnects.

    With that being said, you could make use of this by making it that the prefab that is spawned is a container for one of the cars, and implement a Command/RPC on the prefab to specify which model/car to load within the prefab (and have it so that the loaded car/model becomes a child of the prefab spawned by the network to ensure that it gets removed when the player leaves). This will still pose challenges though, because players would need to disconnect/reconnect in order to change their car.

    A more robust approach would be to ditch your reliance on the "player prefab" of the network manager, and handle the spawning of player cars yourself. This document explains how to handle the spawning of objects over the network yourself: https://docs.unity3d.com/Manual/UNetSpawning.html. It's a little tricky to get wrap your head around it all at first, but if you were to spawn player-owned objects yourself, rather than rely on the NetworkManager, you'll set yourself up with a better foundation to work from.

    Hope this helps!
     
  3. angusmf

    angusmf

    Joined:
    Jan 19, 2015
    Posts:
    261
    Hi there. I spawn my own players as @donnysobonny mentions, but I always spawn the same prefab. The prefab is a relatively generic GameObject that has a "UGO" script attached. UGO, in my case, stand for Unique Game Object. I used them as players and enemies, and could make them generic enough to use for any object I need to keep track of. Each UGO gets a reference to another class full of properties that defines pretty much everything about the UGO, called Breed. I maintain a copy of that object for each different "type" of UGO that I spawn, so if multiple UGOs use the same settings, they can just use the same Breed. When a UGO is spawned, the server sets the breed type to be used and syncs it with a syncvar.

    HOWEVER! Before I converted my game to be multiplayer and use UNET, I had a system in place where the player could switch their control to a new UGO, as if they swapped bodies. When I implemented UNET, I wound up creating a dummy player object to relay messages and make finding references easier when you first connect, and transfer "control" to that. So when my game starts up, if your player is already in the scene, it finds it and you start controlling it. That's the approach I would take in your case. Create the different cars however you need to, then start controlling that object instead of whatever object you spawned. So I actually let the HLAPI NetworkManager just spawn my dummy player object since it was actually easier than doing it myself.

    ---edit---

    The methods you'll need in order to do this are NetworkManager.ReplacePlayerForConnection and maybe NetworkIdentity.AssignClientAuthority. :)

    ---edit---

    I recently realized that there is a significant drawback to using ReplacePlayerForConnection. Once an object is made into a player, it is always a player object. There is no way to remove authority. It seems the intended use is more for changing scenes? My game requires that the player be able to completely change which object they are controlling in the middle of a scene. To make this work, I now call RemoveClientAuthority on the previously controlled object, if any, then call AssignClientAuthority on the newly controlled object. I had to change some references from isLocalPlayer to hasAuthority since the controlled objects are no longer technically players. :)
     
    Last edited: Jun 2, 2017