Adding PhotonView to object already in scene

Options
I'm looking for a way to sync the health of a non-player object, say a box, across all clients.

There doesn't seem to be a good way of searching for answers for this, but I've searched as much as I sanely can.

Details: This box is already a part of the scene, meaning I don't want to instantiate it since it's already there on all clients. A dedicated master client is handling all health changes, so a player attacking the box calls the damage RPC targeting MasterClient which calculates the damage. This change must then be synced with all clients. Also, the master client isn't any of the players, but a sort of copy without a physical presence that handles RPC calls.

I want to be able to create the scene in the Unity editor with all of the boxes with health already in place and have the health synced across the network. I know each box needs a PhotonView but without having to instantiate them all at runtime.

Is this possible? Any advice would be appreciated, while attempting to refrain from commenting on my strategy, if possible.

Thanks.

Comments

  • vadim
    Options
    Add PhotonView in scene object properties when object selected in scene editor.
    Or use prefab with PhotonView for scene box.

    In case of many boxes, consider using one single PhotonView 'Box Manager' object which synchronizes health of every box on change.
  • I've already added the PhotonView component in the box prefab and it's observing a script containing OnPhotonSerializeView() that sends/receives its health. But no synchronization is happening. Do you know what else there is to do?
  • vadim
    Options
    Looks like you did all right.
    Can you log sent/received values in OnPhotonSerializeView()?
    Is it called at all?
  • OnPhotonSerializeView() does not appear to be getting called. Good catch. But now what is the issue?

    In the Unity editor in the Photon View component, it says that Owner and View ID are set at runtime. Is that something that's handled by Photon automatically or do I have to do that manually?
  • Tobias
    Options
    Maybe something is not setup correctly.
    Remove the PhotonView component and add a new one. Drag and drop the script component on that same GO to the "observe" field.
    Doublecheck the spelling and parameters of OnPhotonSerializeView.
    Make sure another player is in the same room or else PUN probably skips calling OnPhotonSerializeView.
  • Tested with two players and still no call.

    Also took a look at PhotonNetwork.InstantiateSceneObject(), but then I get errors complaining that the object is not in a room. But I was hoping to avoid that anyway.
  • Tobias
    Options
    An object in a scene can have a PhotonView and can observe a script just fine. If the object doesn't move, it's likely that no updates are being sent though, due to delta compression or "unreliable on change". This option only sends news when there are some. If the obj is static and does not produce new data, then it won't be sent.
  • So, just having a PhotonView script attached to any object, that is observing a script that contains an OnPhotonSerializeView method, is *literally* ALL you have to do normally for OnPhotonSerializeView to be called? Because that's currently how it is set up (jpitel and I are on the same dev team). Currently we're just looking to observe a Health property. We have a GUI that displays the Health, so we can visually verify it decreases on damage, and the the players (who inherit from the same base class) are able to update correctly when taking damage with OnPhotonSerializeView. So currently the only different between this scene object and the player object is that the scene object is not created with PhotonNetwork.Instantiate, and doesn't read/write position/rotation data. Theoretically it should be working then?
  • So now both players can damage the box and it registers on the master client, but not on the other client. Also, when the box reaches 0 health, we have it call an RPC targeting MasterClient to destroy the box over all clients. However, the RPC is not getting called.

    Can scene objects call RPCs? We're not even getting any errors. Is there a problem with the PhotonView attached to the box? Very confused.
  • So, we've decided to attempt the instantiation method, putting a box placeholder in the scene to mark the transform data for where the box game object will go. Here's our instantiation method where "sceneObjects" is a list of SceneObjectOptions, which contains the information for the box being put into the scene. We've verified that the types and values for each member of sceneObjectData are correct.

    When random is printed, it's "Null". Why?
    void InstantiateSceneObjects() {
    
    	foreach(SceneObjectOptions sceneObjectData in sceneObjects) {
    
    		GameObject random = (GameObject)PhotonNetwork.InstantiateSceneObject(sceneObjectData.prefabName,
    			                            sceneObjectData.position,
    			                            sceneObjectData.rotation,
    			                            sceneObjectData.group,
    			                            null);
    		print (random);
    	}
    }
    
  • Tobias
    Options
    I can't see what values you set per object. What is the group in your case?
    Anything in the log?