In about every game you need to instantiate one or more objects per player. For objects that should synchornize in a networked game, you need to use a special workflow.


PUN can automatically take care of spawning a networked object by passing a starting position, rotation and a prefab name to the PhotonNetwork.Instantiate method. Requirement: The prefab should be available directly under "Resources" folder (to load it at runtime) and it must have a PhotonView component.

Watch out with web players: everything in the resources folder will be streamed at the very first scene per default. Under the web player settings you can specify the first level that uses assets from the resources folder by using the "First streamed level". If you set this to your first game scene, your preloader and main menu will not be slowed down if they don't use the Resources folder assets.

void SpawnMyPlayerEverywhere() 
    PhotonNetwork.Instantiate("MyPrefabName", new Vector3(0, 0, 0), Quaternion.identity, 0); 
    //The last argument is an optional group number, feel free to ignore it for now. 

When you need to setup new GameObjects when they got instantiated, you can implement OnPhotonInstantiate(PhotonMessageInfo info) in a script on them. It's being called with the info who triggered the instantiation. You can setup the GameObject as a player's Tag object, for example:

void OnPhotonInstantiate(PhotonMessageInfo info) 
    // e.g. store this gameobject as this player's charater in PhotonPlayer.TagObject
    info.sender.TagObject = this.GameObject;

Lifetime of Networked Objects

GameObjects created with PhotonNetwork.Instantiate will usually exist as long as you are in the same room. When you swap rooms, objects don't carry over, just like when you switch a scene in Unity.

Whan a client leaves a room, all others destroy the GameObjects owned/created by that player. If this doesn't fit your game logic, you can skip this step. Set PhotonNetwork.autoCleanUpPlayerObjects to false for your game.

Alternatively, the Master Client can create GameObjects that have the lifetime of the room by using PhotonNetwork.InstantiateSceneObject(). The object is not associated with the Master Client but the room. By default, the Master Client controls these objects but you can pass on control with photonView.TransferOwnership().

Check out the Demo for Ownership Transfer

Networked Scene Objects

It is perfectly fine to place PhotonViews on objects in a scene. They will be controlled by the Master Client by default and can be useful to have a "neutral" object to send room-related RPCs.

Important: When you load a scene with networked objects before being in a room, some PhotonView values are not useful yet. For example: You can't check isMine in Awake() when you're not in a room!

Switching Scenes

When you load a scene, Unity usually destroys all GameObjects currently in the hierarchy. This includes networked objects, which can be confusing at times.

Example: In a menu scene, you join a room and load another. You might actually arrive in the room a bit too early and get the initial messages of the room. PUN begins to instantiate networked objects but your logic loads another scene and they are gone.

To avoid issues with loading scenes, you can set PhotonNetwork.automaticallySyncScene to true and use PhotonNetwork.LoadLevel() to switch scenes.

Read Timing for RPCs and Loading Levels

Manual Instantiation

If you don't want to rely on the Resources folders to instantiate objects over the network you'll have to manually instantiate them as shown in the example at the end of this section.

The main reason for wanting to instantiate manually is gaining control over what is downloaded when for streaming web players. The details about streaming and the resources folder in Unity can be found here.

You can send RPCs to instantiate objects. Of course you need some way to tell the remote clients which object to instantiate. You can't just send a reference to a GameObject, so you need to come up with a name or something for it.

As important as the type of object, is a network id for it. The PhotonView.viewID is the key to routing network messages to the correct gameobject/scripts. If you spawn manually, you have to allocate a new viewID using PhotonNetwork.AllocateViewID() and send it along. Everyone in the room has to set the same ID on the new object.

Keep in mind that an RPC for instantiation needs to be buffered: Clients that connect later have to receive the spawn instructions as well.

void SpawnPlayerEverywhere()
    // You must be in a Room already

    // Manually allocate PhotonViewID
    int id1 = PhotonNetwork.AllocateViewID();

    PhotonView photonView = this.GetComponent<PhotonView>();
    photonView.RPC("SpawnOnNetwork", PhotonTargets.AllBuffered, transform.position, transform.rotation, id1);

public Transform playerPrefab; //set this in the inspector 

void SpawnOnNetwork(Vector3 pos, Quaternion rot, int id1)
    Transform newPlayer = Instantiate(playerPrefab, pos, rot) as Transform;

    // Set player's PhotonView
    PhotonView[] nViews = newPlayer.GetComponentsInChildren<PhotonView>(); 
    nViews[0].viewID = id1;

If you want to use asset bundles to load your network objects, all you have to do is to add your own asset bundle loading code and replace the playerPrefab from the example with the prefab from your asset bundle.

 To Document Top