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 
2 - A network view on the Turret, and observing a script which uses OnSerializeNetworkView to send and recieve transform changes. No dice 
3 - A change to Networked Rigidbody to pull the Turret’s local transform and send it with the other data being sent. No dice 
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
For anyone else stuck on this issue (or something similar), here’s what I did.
- 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);
}
}
- The I had to write the RPC function. That was very simple:
@RPC
function SetLocalRotation( newRot : Quaternion ) {
transform.localRotation = newRot;
}
- 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