How to handle return values RPC-style?

I'm in the process of converting a proof of concept from singleplayer to multiplayer, using Photon Networking. I'm a bit puzzled on how to deal with RPCs and return values, or their lack of it, though.

Consider this singleplayer code:

[code2=csharp]if ( Input.GetKeyDown(KeyCode.H) && objectBeingLookedAt.isGatherable ) {
RockResourceController resourceController = objectBeingLookedAt.transform.GetComponent<RockResourceController>();
inventoryController.AddItems ( resourceController.Hatchet () );
}

// Inside RockResourceController
public Dictionary<Item, int> Hatchet () {
Dictionary<Item, int> hatchedItems = new Dictionary<Item, int>();

foreach ( KeyValuePair<Item, int> pair in inventoryController.itemsDictionary ) {
int nrOfItems = Mathf.Clamp( Random.Range(minHatchet, maxHatchet), 1, pair.Value );

hatchedItems.Add ( pair.Key, nrOfItems );
inventoryController.RemoveItem( pair.Key, nrOfItems );
}

if ( inventoryController.isEmpty ) {
Destroy( this.gameObject );
}

return hatchedItems;
}[/code2]
How can/should I convert this logic into "multiplayer mode"? I've tried setting the Hatchet method to be an RPC, and I can of course call it, but how do I get its return value(s) back?

Thanks in advance!

UPDATE:

I came up with a solution. Well, "solution". :) It's something that works, but from my point of view it's less than beautiful;

[code2=csharp]if ( Input.GetKeyDown(KeyCode.H) && objectBeingLookedAt.isGatherable ) {
RockResourceController resourceController = objectBeingLookedAt.transform.GetComponent<RockResourceController>();
resourceController.GetComponent<PhotonView>().RPC ( "Hatchet", PhotonTargets.All, inventoryController.photonView.viewID );
}

// Inside RockResourceController
[RPC]
public void Hatchet ( int playerInventoryPhotonViewId ) {
Dictionary<Item, int> hatchedItems = new Dictionary<Item, int>();

foreach ( KeyValuePair<Item, int> pair in inventoryController.itemsDictionary ) {
int nrOfItems = Mathf.Clamp( Random.Range(minHatchet, maxHatchet), 1, pair.Value );

hatchedItems.Add ( pair.Key, nrOfItems );
inventoryController.RemoveItem( pair.Key, nrOfItems );
}

PhotonView playerInventoryPhotonView = PhotonView.Find( playerInventoryPhotonViewId );
InventoryController playerInventoryController = playerInventoryPhotonView.GetComponent<InventoryController>();

playerInventoryController.AddItems( hatchedItems );

if ( inventoryController.isEmpty ) {
PhotonNetwork.Destroy( this.gameObject );
}
}[/code2]
Any suggestions on how to improve this workflow, if possible?

Thanks!

Comments

  • RPCs don't have a return value, because they could actually be running on any number of remote clients - including none at all. Which return code would you want?
    If you need some reaction, you will have to send another RPC to the origin of some RPC that needs a reply.

    At the moment, I can't analyze your code. It's more effort to analyze what you DO versus what you MIGHT want to do.
    If you can describe what you need to do without posting code, it might help get a more directed reply.