• 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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
Question by Matt- · Jul 13, 2012 at 06:57 PM · networkrpcnetworkview

single call to RPC or Local function?

I find myself writing a lot of code like this:

 public void SelectActionNA(int actionIdx, int actingIdx, )
 {
  if(Network.peerType == NetworkPeerType.Disconnected)
       SelectAction(actionIdx, actingIdx);
  else
       networkView.RPC ("SelectAction", RPCMode.All, actionIdx, actingIdx);
 }


For every action that I want to call either in single player or as an RPC when in an online setting I write an intermediate (non-RPC) function that checks the network status and then calls an RPC or another local function as appropriate.

It feels like there has to be a better way to do that.

Is there a simple straightforward way to write "Do this as an RPC but only if you're connected to the network" without writing a bunch of helper functions to always check the network status and then call it manually?

I feel like networkView.RPC should just call the function locally if not connected, but instead it errors out.

Comment
maraoz

People who like this

1 Show 0
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

2 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by whydoidoit · Jul 13, 2012 at 07:02 PM

Well I write my code like this, so I always call the local function (type safe etc etc):

  [RPC]
  public void SetScore(int score)
  {
  //Run this on everything
  networkView.Others("SetScore", score);
  CurrentScore = score;
  }

Or

 void SetPosition(Vector3 pos, Quaternion rot)
  {
  //Only run on others
  if (!networkView.Others("SetPosition", pos, rot))
      return;
  
  var time = _lastRPCtime = Time.time - _lastSetPosition;
  _lastSetPosition = Time.time;
  position.Duration = Mathf.Min(time, 2f);
  rotation.Duration = position.Duration;
  position.Value = pos;
  rotation.Value = rot;
 
  }

And

 [RPC]
  public void Ready(NetworkViewID viewId)
  {
    //Only run on the server
    if (!networkView.Server("Ready", viewId))
       return;
    ...     
  }

This is the supporting code:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using System;
 using System.Linq;
 using Serialization;
 
 public static class RPCEnabler
 {
  
  
  public static bool Others(this NetworkView networkView, string routineName, params object[] parameters)
  {
  
  if (networkView.isMine)
  {
  
  networkView.RPC(routineName, RPCMode.Others, parameters);
  }
  return !networkView.isMine;
  
  }
  
  public static bool Server(this NetworkView networkView, string routineName, params object[] parameters)
  {
  if(!Network.isServer)
  networkView.RPC(routineName, RPCMode.Server, parameters);
  return Network.isServer;
  }
  
 
 }
Comment
maraoz

People who like this

1 Show 5 · 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 · Jul 13, 2012 at 07:11 PM 0
Share

You can make that server code return that it is the server if the network peer type is disconnected too - I don't need that myself.

avatar image Matt- · Jul 13, 2012 at 08:04 PM 0
Share

Hmmm I'm not sure this fits my situation quit exactly but I like the pattern - having the function call ITSELF as an RPC if it's applicable might be a good solution for me. Thanks!

avatar image whydoidoit · Jul 13, 2012 at 08:38 PM 0
Share

It works really well for me - I get to have optional parameters and never forget the parameter list for an RPC (plus like I said, all the parameters are type checked).

avatar image maraoz · Dec 21, 2012 at 05:19 AM 0
Share

WOW!! This seems like black magic to me... Will have to read more about this Enabler stuff because it seems powerful (I'm still new to C#, as you might guess)

avatar image whydoidoit · Dec 21, 2012 at 08:28 AM 1
Share

There's a lot of Unity magic with networking too - but those are extension methods - very handy, but really just "syntactic sugar"

avatar image

Answer by DoomGoober · Mar 27, 2015 at 02:55 PM

Here's a solution that doesn't require you to modify every RPC method. If you're not connected (ie, single player) it will call the method directly. Otherwise, it will try to RPC the call. Put this in a source code file somewhere in your Unity project:

 using UnityEngine;
 using System.Collections;
 using System;
 using System.Reflection;
 
 public static class NetworkViewExtensionMethods
 {
     public static void LocalOrRPC(this MonoBehaviour monoBehaviour, string name, RPCMode mode, params object[] args)
     {
         if (Network.peerType == NetworkPeerType.Disconnected)
         {
             Type type = monoBehaviour.GetType();
             MethodInfo methodInfo = type.GetMethod(name, BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance);
             methodInfo.Invoke(monoBehaviour, args);
         } 
         else
         {
             monoBehaviour.networkView.RPC(name, mode, args);
         }
     }
 }

Usage is identical to a call to NetworkView.RPC:

 //Call from some MonoBehaviour that has a NetworkView sibling.
 this.LocalOrRPC("SomeMethod", RPCMode.All, "SomeArg", "SomeArg"); //RPCMode.All and RPCMode.AllBuffered are the only two that make sense.

Might be slower than the other solution since it uses reflection but: 1) It's a bit easier to use. 2) The multiplayer RPC call uses reflection anyway! So, if you're calling the function so much that perf is an issue, you're going to run into WORSE problems during multiplayer when the function call overhead will be even higher so you're going to have to fix it anyway.

Comment

People who like this

0 Show 0 · 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

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

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

Does the position change need state synchronization? 2 Answers

RPC Player Name and show it above head 0 Answers

AllocateViewID over RPC but the NetworkView doesn't exist 2 Answers

Help with Network Script. Game with multiple Maps. 2 Answers

View ID AllocatedID: # not found during lookup. Strange behaviour may occur 1 Answer


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