PhotonView with ID 7 has no method "...." marked...
Options
meatloaf
✭
I'm currently trying to send and RPC from a class which is not a Mono. I am using a photonView from another GameObject in order to call the rpc.
Example
From looking at the documentation I thought it didn't matter where you define an RPC as long as you have a photonView to call it from. Am i incorrect on this?
Thanks in advance!
Example
nodeCanvasPhotonView.value.RPC("FindAndSetPlayerReference", RpcTarget.All, PhotonNetwork.LocalPlayer.ActorNumber); [PunRPC] private void FindAndSetPlayerReference(int clientActorID) { var playerGobReference = playerRefSpawnParent.transform.GetComponentsInChildren<PhotonView>() .First(photonView => photonView.OwnerActorNr == clientActorID); matchData.value.NetworkPlayer[clientActorID].Reference = playerGobReference.gameObject; }
From looking at the documentation I thought it didn't matter where you define an RPC as long as you have a photonView to call it from. Am i incorrect on this?
Thanks in advance!
0
Comments
-
In PhotonNetworkPart.cs it searches the RpcList
string inMethodName;
for the supplied method name. It's possible you just need to RefreshRPC's on your PhotonServerSettings asset.
if (rpcData.ContainsKey((byte)5))
{
int rpcIndex = (byte)rpcData[(byte)5]; // LIMITS RPC COUNT
if (rpcIndex > PhotonNetwork.PhotonServerSettings.RpcList.Count - 1)
{
Debug.LogError("Could not find RPC with index: " + rpcIndex + ". Going to ignore! Check PhotonServerSettings.RpcList");
return;
}
else
{
inMethodName = PhotonNetwork.PhotonServerSettings.RpcList[rpcIndex];
}
}
Switching to Debug view on the inspector window when your PhotonServerSettings asset is selected will allow you to see the RPC methods in the list. As long as yourFindAndSetPlayerReference
method is in the list, you're good; maybe - see below. As far as how that list is populated (ie what all objects/types it searches), it is searching for the[PunRPC]
attribute only on theinternal MonoBehaviour[] RpcMonoBehaviours
array. So, it looks like they all must be defined in a MonoBehaviour; but yet there's more - read on.
Finally the binding to which method gets executed is figured out through reflection to invoke the MethodInfo of the method that is named in the string parameter passed in the RPC call ("FindAndSetPlayerReference" in your case). But what class/type is it generating the list of MethodInfo's from, you ask? It does this on aPhotonView
instance that it looks up viaint netViewID = (int)rpcData[(byte)0]; // LIMITS PHOTONVIEWS&PLAYERS
So, now we know that the lookup is somehow tied to PhotonView types - hence the calls are invoked through instances of PhotonView. The last piece of the puzzle comes together in
// ...
PhotonView photonNetview = GetPhotonView(netViewID);PhotonView.RefreshRpcBehaviourCache
:///
So the end result is, not only does your RPC method need to be a Monobehaviour, it also must be attached to the same GameObject as a PhotonView that is consistent for all clients. ///
/// Can be used to refesh the list of MonoBehaviours on this GameObject while PhotonNetwork.UseRpcMonoBehaviourCache is true.
///
/// Set PhotonNetwork.UseRpcMonoBehaviourCache to true to enable the caching.
/// Uses this.GetComponents() to get a list of MonoBehaviours to call RPCs on (potentially).
///
/// While PhotonNetwork.UseRpcMonoBehaviourCache is false, this method has no effect,
/// because the list is refreshed when a RPC gets called.
///
public void RefreshRpcMonoBehaviourCache()
{
this.RpcMonoBehaviours = this.GetComponents();
}0 -
Ah got it thanks so much. This clears it up 👍.0