[Solved] Adding Photon View via code on Unity

Egonaraujo
edited September 2021 in DotNet
Hello!

I am trying to develop a multiplayer funcionality in a Unity-based engine.

The way I went with it is to allow the user to add a "Network Behavior" on its object.
The behavior will add a
PhotonView
and a
PhotonViewTransform
Component on the gameObject

Running in single player works normaly as expected, considering that the views will have no effect

The problem is that, when running in a multiplayer setting, it doesnt update the rotation and position of the objects..
-- On object instantiation
        photonView = gameObject.AddComponent<PhotonView>();
        photonTransformView = gameObject.AddComponent<PhotonTransformView>();
        photonTransformView.m_SynchronizeScale = true;
        photonView.ObservedComponents = new List<Component> { photonTransformView };

-- On multiplayer clicked
        Photon.ConnectUsingSettings
        OnCallbacks >    Photon.JoinRandomRoom / Photon.CreateRoom

The object with the view is already instantiated when the connection with the server is created, the game loads asynchronously before letting the player either "Play" or "Play Multiplayer", and connecting with photon before the play multiplayer option is tapped makes no sense

In a bulletpoint view:
- instantiate object A
- Add PhotonView and PhotonTransformView to object A
- Connect with PhotonNetwork
- Join Photon Room
- "StartGame" (start the runtime mode of the engine)

My question is how to make the PhotonView send updates to the game server? (I still have to manage Master/Client access to the objects, but for now they dont even update positions)

Comments

  • You should not add PhotonViews to objects while not in a room. They define a network id for the object in question and that is per room. If you are outside of rooms, this doesn't do much and is not supported.

    Turn it around and it would work. Join a room, get your actorNumber and assign ViewIds.
    Make sure the PhotonView has some scripts in the Observed list. You can use photonView.FindObservables().
  • Thank you for your input!

    For some reason my transform view wasnt really getting observed so I added some redundant code and it worked.

    The correct path for it that you described also guided me through the correct documentations where I could fix my problem

    For next users (This is a prototype, do not consider this a good architecture decision):
    // Connect / Join Room/ change scenes
            if( IsActive() ) 
            {
                if(PhotonNetwork.IsConnected && photonView == null)
                {
                    photonTransformView = gameObject.AddComponent<PhotonTransformView>();
                    photonTransformView.m_SynchronizeScale = true;
                    photonTransformView.m_SynchronizeRotation = true;
                    photonTransformView.m_SynchronizePosition = true;
                    photonView = gameObject.AddComponent<PhotonView>();
                    photonView.OwnershipTransfer = OwnershipOption.Takeover;
                    photonView.ObservedComponents = new List<Component>() { photonTransformView };
                    photonView.ViewID = PhotonNetwork.AllocateViewID(0);
                }
            }
            else
            { 
                // Destroy(photonView / photonTransformView )
                DestroyPhotonInfrastructure();
            }
    
    // Workaround before actually creating a "ownership controller" kind of behavior
        public void OnPointerDown(PointerEventData eventData)
        {
            photonView.TransferOwnership(PhotonNetwork.LocalPlayer.ActorNumber);
        }
    
  • Glad to know you could make it work.

    Are you sure that AllocateViewID(0) is doing what you want to do? Read it's API reference, please.
    If you allocate the viewID for the player who is creating the PhotonView, the control of the object is already assigned to that player and you don't have to assign it.

    If OnPointerDown can be called frequently, it's not a good idea to call TransferOwnership each time. It queues a network messages, which goes to everyone with some lag. It seems any client can do this, so you will run into situations where several TransferOwnership messages fly around and it's unclear whos' duty it is to send updates of the PhotonView.

    It might be my limited overview of your project but I don't think this is a good approach.