Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by makaka · Jun 29, 2012 at 08:34 AM · networkingnetworkphotonrpcinheritance

RPC and inheritance

Hi, I just tested something and it seems that RPCs in Unity don't support inheritance. Is that correct?

 class Unit : MonoBehaviour 
 {
     [RPC] 
     public void Test () {}
 }

 class Melee : Unit 
 {
 }
 

If I have a unit with Melee script on it, RPC won't be received as RPC function "Test" cannot be found.

 class Unit : MonoBehaviour 
 {
 }

 class Melee : Unit 
 {
     [RPC] 
     public void Test () {}
 }

On the contrary, this works and Test will be executed.

This introduces a set of new problems for us, can you please confirm that this is Unity's standard behaviour? I hope we are doing something wrong...

We are using Photon but that should behave the same way as the integrated networking as far as I know.


EDIT: Photon (PUN) class for the solution below:

1, in case the solution scripts are in the Plugin folder, move them out to your script folder

2, InheritableRPC.cs, replace the second class with this:

 public static class InheritableRPCExtensions
 {
     public class StoredPlayer
     {
         public string ipAddress, guid;
         public int port;
     }
     
     public static void RPCEx(this PhotonView view, string routineName, PhotonTargets targets, params object[] parameters)
     {
         using(var m = new MemoryStream())
         {
             var b = new BinaryFormatter();
             b.Serialize(m, parameters);
             m.Flush();
             var s = Convert.ToBase64String(m.GetBuffer());
             view.RPC("PerformRPCCall", targets, routineName, s);
         }
     }
 
     public static void RPCEx(this PhotonView view, string routineName, PhotonPlayer player, params object[] parameters)
     {
         using(var m = new MemoryStream())
         {
             var b = new BinaryFormatter();
             b.Serialize(m, parameters);
             m.Flush();
             var s = Convert.ToBase64String(m.GetBuffer());
             view.RPC("PerformRPCCall", player, routineName, s);
         }
     }
 }

3, example code. SampleCaller.cs class:

 public class SimpleCaller : MonoBehaviour {
     public PhotonView otherView;
     
     void Start ()
     {
         Network.InitializeServer(200,8081,true);
     }
     
     void OnGUI()
     {
         if(GUILayout.Button("Call Print"))
         {
             otherView.RPCEx("PrintThis", PhotonTargets.All, "Hello World");
         }
     }
 }
Comment
Add comment · Show 9
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Mizuho · Jun 29, 2012 at 09:04 AM 0
Share

http://forum.unity3d.com/threads/45224-Override-RPC-functions

It looks like the RPC is supposed to be declared virtual and then overwritten in all child classes...

avatar image whydoidoit · Jun 29, 2012 at 09:06 AM 0
Share

Yeah, I think it's pretty easy to add something that stops that being the case for the cost of a reflection lookup and Invoke.

avatar image makaka · Jun 29, 2012 at 09:18 AM 0
Share

To $$anonymous$$izuho: Yes, that might work in a simple example but can you imagine an RTS with 50 unique units? Every time you need to make a new unit, you would have to override all the RPC just because your new unit has a tiny bit different feature. Introducing a new RPC is even worse, it would be necessary to go through all the units and override it there. I think this is fairly hard to manage in the long run.

Thank you for the input :]

avatar image flamy · Jun 29, 2012 at 09:51 AM 0
Share

this is because RPC's are meant to be called with the networkview component, in this case base class is not having it. also when you register a rpc function, it creates an unique rpc id for it, with which it is getting called.

did you try calling like

"base.Test" in the parameter for RPC ins$$anonymous$$d of just "Test".

btw i couldnt check at my end so im not sure if it would work.

avatar image whydoidoit · Jun 29, 2012 at 12:40 PM 2
Share

@flamy - got it working :)

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by whydoidoit · Jun 29, 2012 at 11:51 AM

Ok so you can't do that normally but it is possible to create a work around that will work generically on all objects and classes. To do this you create a normal RPC script that itself defers to the base classes of the other components. This works well generically but there may be times when it would be faster to do this directly by writing code for specific instances. Presuming RPC calls are already expensive and not frequent it should be fine to do it this way.

So I've create a script that you attach to the game objects that have inherited scripts attached to them. This handles the real RPC call and then forwards it on to the inherited components.

To use it you use networkView.RPCEx(normal parameters) and that's it.

You can also pass more complex objects as parameters to RPCEx - but you cannot pass NetworkPlayer or NetworkViewID so those would have to use normal RPC for setup. After that I'm presuming these parameters are not often passed in the case where you want inherited execution (it would be possible with more work to make those passable too).

You can get the code from here

Comment
Add comment · Show 13 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · Jun 29, 2012 at 11:53 AM 0
Share

If you were calling from Unity Script you would have to call it like this:

  InheritableRPCExtensions.RPCEx(networkView, /* Normal Parameters */);
avatar image makaka · Jun 29, 2012 at 12:16 PM 0
Share

I'm checking the code now. "namespace name `Serialization' could not be found". There's several namespaces with this name. I'm using UnityEngine.Serialization for now. Looks promising so far, thank you

EDIT: taking back the path comment, it's fine

avatar image whydoidoit · Jun 29, 2012 at 12:23 PM 0
Share

Ugh - just delete that you don't need it (damn, will fix the package). That's my UnitySerializer, just accidentally in there, it doesn't need it.

avatar image whydoidoit · Jun 29, 2012 at 12:26 PM 0
Share

Package has the Serialization namespace removed now.

avatar image whydoidoit · Jun 29, 2012 at 12:31 PM 0
Share

And I've added an example test scene to show it working.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

7 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

PhotonView with ID has no method marked with the [PunRPC](C#) property! BUT IT HAS ??? 1 Answer

Stuck on ConnectingToNameServer 0 Answers

Best Solution for Multiplayer Shooting 1 Answer

Update int value with photon rpc? 0 Answers

how can i set multiplayer online in my ludo game as i have many objects for a player like dice and 4 players for each player but i can only add one player . What i make my player 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges