- Home /
UNET Rpc calls wrong inherited script
Hi All,
So here's the setup: I have a GameObject with a Network Identity and Local Player Authority. I have a base class and two child classes that extend the base class. The base class makes an Rpc call.
I want to put both of these child classes on the same object, but when I do that, the Rpc call executes on the first class attached to the object, rather than the one that made the call.
Of course, I could have a child object with a separate NetworkIdentity store one of the Child classes, but I wanted to know whether this is a bug in Unity, or if it's intended behavior, or if I'm just doing something wrong.
The "Base" class looks something like this:
using UnityEngine;
using UnityEngine.Networking;
public abstract class Base : NetworkBehaviour {
// The client's player object
public GameObject player;
public void Execute() {
if(player.GetComponent<NetworkIdentity>().isServer)
{
RpcExecute();
} else {
CmdExecute();
}
}
[Command]
public void CmdExecute() {
RpcExecute();
}
[ClientRpc]
public void RpcExecute() {
Actions();
}
public abstract void Actions();
}
And the two sub-classes, ChildA and ChildB, both look like this:
using UnityEngine;
using UnityEngine.Networking;
public class ChildX : Base {
public override void Actions {
// Execute some actions here
}
}
Any feedback is appreciated!
Same problem here, Example setup: Spell is base class, HealSpell and DamageSpell extend Spell. Both heal and damage spell are attached to the Player object. Spell class contains an RPC from server to client, but if the damagespell is the subclass, the RPC in spell will still be exectued on the client side on the healspell instance. (the first one it encountered.)
This is a very annoying and seems like a huge bug to me.
Anyone has a solution for this?
Answer by EAST-DATA · Apr 10, 2017 at 09:10 AM
public int rpcId;//Specific id
private int mRpcExecuteHash ;
private string mRpcExecuteName ;
private NetworkWriter mRpcExecuteWriter = new NetworkWriter();
public override void OnStartClient()
{
base.OnStartClient();
mRpcExecuteName = "RpcExecute:" + rpcId.ToString() + netId.ToString();
mRpcExecuteHash = mRpcExecuteName .GetHashCode();
RegisterRpcDelegate(GetType(), mRpcExecuteHash , RpcExecute);
}
public override void OnStartServer()
{
base.OnStartServer();
mRpcExecuteName = "RpcExecute:" + rpcId.ToString() + netId.ToString();
mRpcExecuteHash = mRpcExecuteName .GetHashCode();
}
[Command]
public void CmdExecute() {
mRpcExecuteWriter .StartMessage(MsgType.Rpc);
mRpcExecuteWriter .WritePackedUInt32((uint)mRpcExecuteHash );
mRpcExecuteWriter .Write(netId);
//mRpcExecuteWriter .Write(some more data);
mRpcExecuteWriter .FinishMessage();
SendRPCInternal(mRpcExecuteWriter , 0, mRpcExecuteName );
}
void RpcExecute(NetworkBehaviour obj, NetworkReader reader)
{
//read data
}
Not the best solution, but it works for me. Thanks.
This was very helpful, and actually got my project back on track. Thanks a lot!
On a side note: Ins$$anonymous$$d of exposing the RPC ID to the inspector, you could use the index of this component instance in your object's components, and therefore assuring that each instance of the derived script on your object has a different ID that is consistent in the structure of your prefab.
Your answer
Follow this Question
Related Questions
Changing variable value Network 1 Answer
How to send player reference over network 1 Answer
Why do I keep getting UNetWeaver error: GetWriteFunc recursion depth exceeded for NetworkInstanceId 2 Answers
OnDisconnectedFromServer ignores inheritance 1 Answer
Using command attribute in child classes 0 Answers