Problem Updating all clients when Child Object's Local Rotation changes

Hey gang!

I’ve been giving myself a crash course on non-authoritative servers, and it’s been going great thus far. However, I’ve run into a small problem that I’m hoping others have handled in the past.

I’m writing a simple tank-type of game. The player prefab hierarchy is as follows:
Root Object (empty object with many scripts attached such as networked rigidbody, fps walker, etc)
|_ Mesh Object (Mesh Renderer, Mesh Filter, Animations)
|_ Rig / Bone structure
|____ Turret, child of rig structure (MouseLook script attached)

The Turret is where I’m having trouble. I want the other players to know when I’m aiming at them, but I cannot get the prefabs on the remote clients to update when I turn the turret. The MouseLook script was altered to run in LateUpdate, so that animations blend with the manual manipulation of the rig/bones, but nothing else is too different from what I see others doing.

What I’ve tried:
1 - A network view on the Turret, and observing the Transform of the Turret. No dice :frowning:
2 - A network view on the Turret, and observing a script which uses OnSerializeNetworkView to send and recieve transform changes. No dice :frowning:
3 - A change to Networked Rigidbody to pull the Turret’s local transform and send it with the other data being sent. No dice :frowning:

The last idea I have is to use straight RPC calls from the Turret (possibly in MouseLook when a change is detected). I haven’t finished coding it yet, but I wanted to get the question out there in case someone has already defeated this particular challenge. Thanks guys!

Brett

RPCs worked :slight_smile: For anyone else stuck on this issue (or something similar), here’s what I did.

  1. First, I had to modify MouseLook so that anytime the transform.localRotation was updated, I made an RPC call (remember, this is non-authoritative design). Here’s an example of how I modified the MouseLook when controlling the X and Y axis:
if (axes == RotationAxesMech.MouseXAndY)
{
	// Read the mouse input axis
	rotationX += Input.GetAxis("Mouse X") * sensitivityX;
	rotationY += Input.GetAxis("Mouse Y") * sensitivityY;

	rotationX = ClampAngle (rotationX, minimumX, maximumX);
	rotationY = ClampAngle (rotationY, minimumY, maximumY);
		
	// The following calculations are very strange because the bone structure of the models I am using are not properly rotated
	xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.left);
	yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.forward);
	var tempRot : Quaternion = originalRotation * xQuaternion * yQuaternion;
	lastRotation = transform.localRotation; // class variable, set this at the top of the script!  We use it to store the delta between frames, and then decide whether to make an RPC call or not
		
	// We only want to send out true updates.  Don't spam network traffic if we don't need to!
	//Debug.Log("Rotation angle difference = " + Quaternion.Angle(lastRotation, tempRot));
	if( Quaternion.Angle(lastRotation, tempRot) == 0 )
		return;
	else {
		transform.localRotation = tempRot;
		lastRotation = transform.localRotation;
		networkView.RPC("SetLocalRotation", RPCMode.Others, tempRot);
	}
}
  1. The I had to write the RPC function. That was very simple:
@RPC
function SetLocalRotation( newRot : Quaternion ) {
	transform.localRotation = newRot;
}
  1. Done!

Yes. I tried serializing stuff forever ago when I first started networking, and it never worked. From then on, I have always used rpcs, and they work great. I recommend you continue using them. Good job.

Heya Cerebrate - I totally agree! Serializing has never really worked for me. I know it has everything to do with my implementation, because NetworkedRigidbody seems to work fine using it, ha! RPCs is just easier though, you are 100% right