- Home /
Is it possible to RPC a C# extension method?
I've tested the below code, but it fails due to it not recognizing a "RemoveRPCsOnServer" on the other end. The method is called like gameObject.networkView.RemoveRPCsOnServer (). Is this a limitation of attributes & extension methods, or is it a limitation in how NetworkView looks for RPC-able methods? Any suggestions for workarounds would be appreciated!
using UnityEngine;
namespace ExtensionMethods
{
public static class NetworkViewExtensions
{
/** Same as Network.RemoveRPCs, but ensure it is executed on the server. */
[RPC]
public static void RemoveRPCsOnServer (this NetworkView networkView)
{
if (Network.isServer) {
Network.RemoveRPCs (networkView.viewID);
} else {
networkView.RPC ("RemoveRPCsOnServer", RPCMode.Server);
}
}
}
}
I'm not going to post an actual answer, to increase your chances of running into someone who knows for sure. But in the documentation for RPC (http://docs.unity3d.com/Documentation/Components/net-RPCDetails.html) it says that RPC's are limited to only receiving a handful of parameter types (int, string, etc). Your extension method (by necessity) takes a NetworkView object as a parameter, and so I'm guessing this won't work.
Thanks for the response - but I'm not actually passing a NetworkView as the parameter - NetworkView is 'this'. Internally, I'm assu$$anonymous$$g networkView.RPC passes the NetworkViewID of the NetworkView, then on the other end looks up the NetworkView that has the given NetworkViewID, and looks for the named object on any of the other components assigned to the GameObject.
There's no problem with the serialization - the networkView.RPC ("RemoveRPCsOnServer", RPC$$anonymous$$ode.Server) call fails because it can't find the RemoveRPCsOnServer method, not because it can't serialize the data. :-)
If you want to see how I finally solved it:
https://github.com/jorgenpt/unity-utilities/blob/master/Behaviours/NetworkDestroyer.cs
Answer by whydoidoit · Oct 08, 2012 at 07:51 PM
No I'm afraid not. It has to be an actual method on the class. You can pass a NetworkViewID but not a NetworkView.
What do you mean, "an actual method on the class"? I think the problem is that NetworkViews don't look inside the NetworkView class for potential RPC recipients, only on other assigned Components (or possibly $$anonymous$$onoBehaviours). The way extension methods work, this creates an actual instance method called "RemoveRPCsOnServer" on the NetworkView class.
I mean
networkView.RPC ("RemoveRPCsOnServer", RPC$$anonymous$$ode.Server);
Cannot call RemoveRPCsOnServer because that method is not in any script attached to the object with the networkView.
Extension methods do not create a new instance method - that would break encapsulation. They are syntactic sugar for calling your method the normal way:
NetworkViewExtensions.RemoveRPCsOnServer(networkView);
Which you will find you can still do (and must when calling things that were written as extension methods when using Unity Script).
Yeah, someone else just brought this up as well. I thought extension methods worked like classes in Ruby (where you can "re-open" the class definition and add new, first-class methods). Oh well, I guess I have to find a new way to approach this problem.
There are some very cool things in Ruby I reckon. Wish we could do that in C#...
Actually I do something a bit like what you are trying to do. I have this method of having the call written on the class, but use an extension method to decide whether to execute it or pass it to the server. It's kind of like what you are doing but backwards. I'll post something here in a few - just on a support call
Your answer
Follow this Question
Related Questions
Network.Instantiate doesn't update in Hierarchy? 0 Answers
Networking RPC sends to wrong target 0 Answers
Multiple Cars not working 1 Answer
SyncVar issue 0 Answers
ClientRPC not getting sent. 0 Answers