Troubles with instantiation and ownership

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

Troubles with instantiation and ownership

Chernikov
2019-11-08 01:21:32

I'm experiencing some problems with instantiation and ownership in photon. I want to instantiate an object locally via rpc on everyone in the room and set ownership on that object in that rpc.
My code of spawner

public class PlayerSpawner : MonoBehaviourPunCallbacks {  
        [SerializeField]  
        RpcTarget rpcTarget = RpcTarget.AllBufferedViaServer;

        void Awake() {  
            Vector3 position = Vector3.zero + Vector3.left * PhotonNetwork.LocalPlayer.ActorNumber;  
            Color color = Color.Lerp(Color.red, Color.green, (float) PhotonNetwork.CurrentRoom.PlayerCount / 10);  
            photonView.RPC(nameof(InitPlayerLocally), rpcTarget, PhotonNetwork.LocalPlayer, position, JsonUtility.ToJson(color));  
            Debug.LogError($"ID {PhotonNetwork.LocalPlayer.ActorNumber}");  
            if (PhotonNetwork.IsMasterClient)  
                Debug.LogError("Master");  
        }

        [PunRPC]  
        void InitPlayerLocally(Player owner, Vector3 position, string color) {  
            Debug.LogError($"[RPC] from {owner.ActorNumber}");  
            var o = Instantiate(Resources.Load("Player"));  
            o.transform.position = position;  
            o.GetComponent().material.color = JsonUtility.FromJson(color);

            // it doesn't make game object true networked  
            // if owner leaves - game object still exists in the scene. Why?  
            o.GetPhotonView().TransferOwnership(owner);  
            PhotonNetwork.AllocateViewID(o.GetPhotonView());  
            PhotonNetwork.RegisterPhotonView(o.GetPhotonView());  
        }  
}

Player's photon view owner type is set to takeover
RPCs are buffered via server and I suppose they must be executed in the order they were sent and for players that come later, but it is not true.

Here is an example of 4 apps were run simultaneously: https://imgur.com/brfJBlD
Here is an example of 4 consecutive runs: https://imgur.com/CnaanLH

As I thought it should work this way:

  1. Each player joining room creates an RPC with some initialization data
  2. That player executes all RPC from the very old one up to the its own one
  3. Each player in the room (Including RPC sender) execute the last sent RPCs
    2.1. Each player instantiates a local object
    2.2. After instantiation it transfers ownership of that object to the sender player
  4. Newly created object is instantiated on each client and owner set to actual and the same player on each client
  5. After player X leaves the room - each object, owned by X, get automatically destroyed on each other client, because they were already manually linked to that player

Summary:

  1. Why buffered RPCs are not called on newly joined players?
  2. Why owned object not destroyed after leaving the room?

Playable unity package of the scene: https://drive.google.com/open?id=1nLh8Tf1R9x3cunfFZrPzK-uq6xZW3lWF

Comments

Chernikov
2019-11-08 01:24:53

To set up the project to use my package you need to add TestPUN and TestPUN-Transition scenes into build list in the same order

Chernikov
2019-11-08 01:39:10

The same story with events.

new RaiseEventOptions {  
  Receivers = ReceiverGroup.All,  
  CachingOption = EventCaching.AddToRoomCache  
}

Doen't make any different than RPC

jeanfabre
2019-11-08 10:32:04

Hi,

Too many questions in one thread:) make sure you create distinct threads for each issues, it will be easier for everyone. Let's try to tackle things in small chuncks:

  • instantiation

I don't think it's a good idea to instantiate via rpc, it doesn't make sense, since pun provides the mechanism to safely and reliably instantiate network objects across all connected clients. I strongly advise to use that instead. Use PhotonNetwork.Instantiate()

  • ownership:

OwnerShip transfert can not be authoritative, it follows a procedure. Only the masterClient can autoritativly assign ownership, other clients must request it. PLease read through the pun classic sample, the principle is the same for v2: https://doc.photonengine.com/en-us/pun/v1/demos-and-tutorials/package-demos/ownership-transfer

  • RPC orders

I think you are running into typical race condition issues, if the rpc is sent before a user joined, that user will not get it, this is not a good idea to have newly joining players to rely on rpc being sent around the same time.

  • owner objects and destruction

again, I think your objects are wrongly setup and therefore not properly owned which means they won't get destroyed automatically when the player leave the room. Make sure you use photonNetwork.Instantiate() to make this process reliable. Warning. Owner ship transfer still belongs to the original owner for destruction,


Maybe you could explain what you are after? I think you are getting side tracked here and it's probably a good idea if you could explain what you want so that I can put you on the right path.

Bye,

Jean

Back to top