Troubles with instantiation and ownership

Options
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<GameObject>("Player"));
            o.transform.position = position;
            o.GetComponent<Renderer>().material.color = JsonUtility.FromJson<Color>(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
2. 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
3. Newly created object is instantiated on each client and owner set to actual and the same player on each client
4. 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

Answers

  • Chernikov
    Chernikov
    edited November 2019
    Options
    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
    Chernikov
    edited November 2019
    Options
    The same story with events.
    new RaiseEventOptions {
      Receivers = ReceiverGroup.All,
      CachingOption = EventCaching.AddToRoomCache
    }
    Doen't make any different than RPC
  • jeanfabre
    Options
    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