Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Unity Multiplayer Games

You're reading from   Unity Multiplayer Games Take your gaming development skills into the online multiplayer arena by harnessing the power of Unity 4 or 3. This is not a dry tutorial ‚Äì it uses exciting examples and an enthusiastic approach to bring it all to life.

Arrow left icon
Product type Paperback
Published in Dec 2013
Publisher Packt
ISBN-13 9781849692328
Length 242 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Alan R. Stagner Alan R. Stagner
Author Profile Icon Alan R. Stagner
Alan R. Stagner
Arrow right icon
View More author details
Toc

Table of Contents (9) Chapters Close

Preface 1. Unity Networking – The Pong Game FREE CHAPTER 2. Photon Unity Networking – The Chat Client 3. Photon Server – Star Collector 4. Player.IO – Bot Wars 5. PubNub – The Global Chatbox 6. Entity Interpolation and Prediction 7. Server-side Hit Detection Index

Loading networked levels

There are a few tricks to loading networked levels in the Unity game engine. If you just use Application.LoadLevel, you'll encounter a number of issues; specifically you may find that a client connecting to the game won't see any objects that were instantiated via Network.Instantiate. The reason for this is because the level loading process doesn't happen instantly—it actually takes two frames to complete. This occurs after the list of networked objects was received, so the load process will delete them.

Note that Application.LoadLevel is purely client side. Unity imposes no limitations on which level a client or server loads in a networked game. In fact, it's entirely possible that you might have different levels within a networked session, and this is what Network.SetLevelPrefix is for. Each of these levels is assigned some kind of "ID" that uniquely identifies the level. Before loading the level you would use Network.SetLevelPrefix. This essentially separates players into channels, so all players with level prefix 0 are separate from players with level prefix 1, for example.

Note that if your game needs all clients to load the same level, you'll have to ensure this yourself. If a client has a different level loaded than the host, without setting the level prefix to something different than the host, the client might see some odd situations, such as players floating or sunk into the ground (a player could be standing on a bridge in one level, and a different level at the same position might have a building; so the player would appear to be clipped into the building).

The correct way to load levels in a networked game, is to first disable the network queue, load the level, wait two frames, and then re-enable the network queue. This means any incoming messages will not be processed, and will instead be buffered until the new level has completely finished loading.

Let's write a simple network level loader that will handle all of these for us. It's designed as a singleton so we don't need one present in the scene (one will automatically be created):

using UnityEngine;
using System.Collections;

public class NetworkLevelLoader : MonoBehavior
  {
  // implements singleton-style behavior
  public static NetworkLevelLoader Instance
  {
    get
    {
      // no instance yet? Create a new one
      if( instance == null )
      {
        GameObject go = new GameObject( "_networkLevelLoader" );
        // hide it to avoid cluttering up the hieararchy
        go.hideFlags = HideFlags.HideInHierarchy;
        instance = go.AddComponent<NetworkLevelLoader>();

        // don't destroy it when a new scene loads
        GameObject.DontDestroyOnLoad( go );
      }
      return instance;
    }
  }
  private static NetworkLevelLoader instance;

  public void LoadLevel( string levelName, int prefix = 0 )
  {
    StopAllCoroutines();
    StartCoroutine( doLoadLevel( levelName, prefix ) );
  }

  // do the work of pausing the network queue, loading the level, waiting, and then unpausing
  IEnumerator doLoadLevel( string name, int prefix )
  {
    Network.SetSendingEnabled( 0, false );
    Network.isMessageQueueRunning = false;

    Network.SetLevelPrefix( prefix );
    Application.LoadLevel( name );
    yield return null;
    yield return null;

    Network.isMessageQueueRunning = true;
    Network.SetSendingEnabled( 0, true );
  }
}

You can now replace any calls to Application.LoadLevel with NetworkLevelLoader.Instance.LoadLevel. For example, the server might call an RPC which loads the level via the helper class we just wrote, as a buffered RPC so that all clients connecting will automatically load the level.

Note

If your server needs to change level during the connection, for example, in many FPS games players can vote on a new map at the end of a round, things get a bit more complicated. The server should first delete all networked objects belonging to players, remove RPCs from all players (via Network.RemoveRPCs), and then call the load-level RPC.

You have been reading a chapter from
Unity Multiplayer Games
Published in: Dec 2013
Publisher: Packt
ISBN-13: 9781849692328
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image