8 - Player Instantiation

This section will cover "Player" prefab instantiation over the network and implement the various features needed to accommodate automatic scenes switches while playing.

Contents

Instantiating the Player

It's actually very easy to instantiate our "Player" prefab. We need to instantiate it when we've just entered the room, and we can rely on the GameManager Script Start() Message which will indicated we've loaded the Arena, which means by our design that we are in a room.

  1. Open GameManager Script
  2. In the Public Variables region add the following variable

  3. In the Start() method, add the following and save GameManager Script

  4. Save GameManager Script

This exposes a public field for you to reference the "Player" prefab. It's convenient, because in this particular we can drag and drop directly in the "GameManager" prefab, instead of in each scenes, because the "Player" prefab is an asset, and so the reference will be kept intact (as opposed to referencing a GameObject in a hierarchy, which a Prefab can only do when instantiated in the same scene).

WARNING: Always make sure Prefabs that are supposed to be instantiated over the network are within a Resources folder, this is a Photon Requirement.

GameManager Inspector
GameManager Inspector

Then, on Start(), we do instantiate it (after having properly check we have a "Player" prefab referenced)

Notice that we instantiate well above the floor (5 units above while the player is only 2 units high). This is one way amongst many other to prevent collisions when new players join the room, players could be already moving around the center of the arena, and so it avoids abrupt collisions. A "falling" player is also a nice and clean indication and introduction of a new entity in the game.

However, this is not enough for our case, we have a twist :) When other players will join in, different scenes will be loaded, and we want to keep consistency and not destroy existing players just because one of them left. So we need to tell Unity to not destroy the instance we created, which in turn implies we need to now check if instantiation is required when a scene is loaded.

Back to Content

Keeping track of the player instance

  1. Open PlayerManager Script
  2. In the "Public Variables" Region, add the following

  3. In the Awake() method, add the following

  4. Save PlayerManager Script

With these modifications, we can then implement inside the GameManager Script the check to only instantiate if necessary.

  1. Open GameManager Script
  2. Surround the instantiation call with a if statement

  3. Save GameManager Script

With this, we now only instantiate if the PlayerManager doesn't have a reference of an existing instance of the localPlayer.

Manage player position when outside the arena

We have one more thing to watch out for. The size of the Arena is changing based on the number of players, which means that there is a case where if one player leave and the other players are near the limits of the current arena size, they will simply find themselves outside the smaller arena when it will load, we need to account for this, and simply reposition the player back to the center of the arena in this case. It's something that is an issue in your gameplay and level design specifically.

There is currently an added complexity because Unity has revamped "Scene Management" and Unity 5.4 has deprecated some Callbacks, which makes it slightly more complex to create a code that works across all Unity versions (from Unity 4.7 to the latest). So we'll need different code based on the Unity version. It's unrelated to Photon Networking, but however important to master for your projects to survive updates.

  1. Open PlayerManager Script
  2. At the top of the script add the following define

  3. At the end of the Start() method, add the following code

  4. Add the following two methods inside the "MonoBehaviour CallBacks" region

  5. Save PlayerManager Script

What this new code does is watching for a level being loaded, and raycast downwards the current player's position to see if we hit anything. If we don't, this is means we are not above the arena's ground and we need to be repositioned back to the center, exactly like when we are entering the room for the first time.

If you are on a Unity version lower than Unity 5.4, we'll use Unity's callback OnLevelWasLoaded. If you are on Unity 5.4 or up, OnLevelWasLoaded is not available anymore, instead you have to use the new SceneManagement system. Finally, to avoid duplicating code, we simply have CalledOnLevelWasLoaded method that will be called either from OnLevelWasLoaded or from the SceneManager.sceneLoaded callback.

Back to Content

Next Part.
Previous Part.

 To Document Top