Network RPC only partly working

Some really odd problems here so pardon the long description.

I am making a network multiplayer game where the players are not always going to be on the same level at the same time, but what they do can affect other players currently playing in other levels. For example, I want Player A on Level 1 to be able to press a button that causes a block to slide for Player B who is already on Level 2. (This block might crush Player B if he doesn’t notice it and get out of the way in time.)

Because players will not be on the same level at the same time, it doesn’t work to have the block start sliding on Player A’s computer and then just use state synchronization to make the block also slide on Player B’s computer. I need to use remote procedural calls instead.

I got the RPC partly working for pushing the block in a Z+ direction. Here’s what I did (and the script is pasted below). For Player A’s computer (the sending computer), I created a UI button named “Push Forward,” and then set its OnClick() to invoke the function onPush(“Forward”) in a C# script attached to another object in the scene. The onPush(“forward”) function then triggers two RPCs:

  • The first RPC simply causes Player B’s computer (the
    receiving computer) to print the
    message “Forward push.” And that
    works just fine. Player B’s
    console prints “Forward
    push” just like it should.
  • The second RPC invokes a function
    remoteControl(string whichAxis) on
    Player B’s computer. The first thing
    the remoteControl function should do
    is print the whichAxis parameter
    (Debog.Log (whichAxis)), which in
    this case would be “Forward.” But
    it doesn’t print.
    However, the
    next thing it should do is to
    increment a variable transZ by 1
    (transZ += 1f). Then the fixedUpdate
    function has a
    Rigidbody.AddRelativeForce that uses
    transZ as the Z variable. And that
    sort of works, but not completely. It does start sliding
    the block, but only to a certain
    speed – it starts slow and gets a
    little faster, but then reaches a
    speed after which it won’t get any
    faster no matter how many times I
    click the “Push Forward”
    button on Player A’s computer.

Now here’s where it get even more weird. I created a “Push Reverse” button on Player A’s computer, which sends the same kinds of messages to Player B’s computer except the print message is “Reverse push” (which works just as it should) and the remoteControl parameter is “Reverse.” With that parameter, the transZ variable is decremented by 1 (transZ -= 1f). But that doesn’t work at all. I can press “Push Reverse” on Player A’s computer dozens of times and Player B’s computer will always print “Reverse push” in the console but the block will never move. And none of the other Debog.Log statements work either.

Please note, when I say something is not working, I don’t mean I’m receiving errors. I receive no errors at all when I compile this code. It just doesn’t work.

In case you’re wondering, every involved game object has a Network View component, so that shouldn’t be the problem. And, if it matters, I’m using Mac OS X (Yosemite) with Unity 4.6.3f1. My local build of the Unity master server is handling the network communication.

Okay, as promised, my code is below. The code both for sending and receiving is all in the same script, just to make it easier. I’ve also inserted comments to show what works and what doesn’t.

public class pushRemoteControl : MonoBehaviour {

	public NetworkView nView;

	public float speed;
	private float transX;
	private float transY;
	private float transZ;

	void Start ()
	{
		nView = GetComponent<NetworkView>();
		transX = 0f;
		transY = 0f;
		transZ = 0f;
	}

	public void onPush (string pushType) // this whole function works, at least from Player A's perspective
	{
		if (pushType == "Forward")
		{
			nView.RPC ("printText", RPCMode.Others, "Forward push"); // taking this out doesn't change my problem
			nView.RPC ("remoteControl", RPCMode.Others, "Forward");
		}
		else if (pushType == "Reverse")
		{
			nView.RPC ("printText", RPCMode.Others, "Reverse push"); // taking this out doesn't change my problem
			nView.RPC ("remoteControl", RPCMode.Others, "Reverse");
		}
	}

	[RPC]
	void printText (string text) // this function works fine every time
	{
		Debug.Log (text);
	}

	[RPC]
	void remoteControl (string whichAxis)
	{
		Debug.Log (whichAxis); // this line doesn't work
		
		if (whichAxis == "Forward")
		{
			transZ += 1f; // this line sort of works, but does not continue speeding up the block after a certain point
			Debug.Log (transZ); // this line doesn't work
		}
		else if (whichAxis == "Reverse")
		{
			transZ -= 1f; // this line doesn't work
			Debug.Log (transZ); // this line doesn't work
		}
	}
	
	void FixedUpdate ()
	{
		rigidbody.AddRelativeForce (transX * speed * Time.deltaTime, transY * speed * Time.deltaTime, transZ * speed * Time.deltaTime, ForceMode.Impulse);
		// using AddForce instead doesn't solve my problem
		// changing Forcemode to Force doesn't solve my problem
	}
	
}

Thanks again.

After a huge amount of trial-and-error (removing components one by one to see if they were the problem), I figured out that the problem was another script attached to the block. It was a script that allowed me to move it directly using the arrow keys (it was a test script; so when sitting at Player B’s computer I could move the block around without network communication). Somehow that was intercepting the RPC calls, I guess. But now that I have that fixed, another problem has come up, which I will post in a separate thread . . .