Page 1 of 1

Rotation sent to server

Posted: Thu 08 Dec , 2011 8:06 pm
by Azarael
Trying to fix the BallisticTurret issue where the aim is off.

There's a function called UpdateRocketAcceleration in BallisticTurret which, if the turret is locally controlled, calls a function which is replicated to the server, ServerTurretRotation, with a variable GunRotation as a parameter NewGunRot. This then assigns NewGunRot to the server's GunRotation variable.

I've logged both variables - Client's GunRotation before ServerTurretRotation is called, and the server's GunRotation after NewGunRot has been assigned, and they're different, for some reason. For that matter, the base Rotation of the server' turret and the client's turret are different, too. Anyone have any ideas why?

Relevant sections

Code: Select all

replication
{
	unreliable if (Role == ROLE_Authority && !bNetOwner && bNetDirty)
		GunRotationYaw, GunRotationPitch;

	reliable if (Role < ROLE_Authority)
		ServerTurretRotation;
}

function UpdateRocketAcceleration(float DT, float YawChange, float PitchChange)
{
    local rotator TempRot;

	if (AIController(Controller) == None)
	{
		GoalRotation.Yaw = Clamp(GoalRotation.Yaw + DT * YawChange * YawSpeed, GoalYawBounds.Min, GoalYawBounds.Max);
		GoalRotation.Pitch = Clamp(GoalRotation.Pitch + DT * PitchChange * PitchSpeed, GoalPitchBounds.Min, GoalPitchBounds.Max);
	}
	else
		BotUpdateAcceleration(DT);

//	if (bDriverOutOfRange)
//		return;
	if (!bDriverOutOfRange || Normal(Driver.Location - Location) Dot Vector(Rotation+GoalRotation) < Normal(Driver.Location - Location) Dot vector(Rotation+CameraDirection))
	{
		GunRotation.Yaw += Clamp(GoalRotation.Yaw - GunRotation.Yaw, DT * -GunYawSpeed, DT * GunYawSpeed);
		GunRotation.Yaw = Clamp(GunRotation.Yaw, GunYawBounds.Min, GunYawBounds.Max);

		CameraRotation.Yaw += Clamp(GoalRotation.Yaw - CameraRotation.Yaw, DT * -CamYawSpeed, DT * CamYawSpeed);
		CameraRotation.Yaw = Clamp(CameraRotation.Yaw, CamYawBounds.Min, CamYawBounds.Max);

		TempRot.Yaw = CameraDirection.Yaw + Clamp(GunRotation.Yaw - CameraDirection.Yaw, DT * -CamTrackYawSpeed, DT * CamTrackYawSpeed);
	}
	GunRotation.Pitch += Clamp(GoalRotation.Pitch - GunRotation.Pitch, DT * -GunPitchSpeed, DT * GunPitchSpeed);
	GunRotation.Pitch = Clamp(GunRotation.Pitch, GunPitchBounds.Min, GunPitchBounds.Max);

	UpdateSimulatedGunRotation();
	UpdateWeaponRotation();

	CameraRotation.Pitch += Clamp(GoalRotation.Pitch - CameraRotation.Pitch, DT * -CamPitchSpeed, DT * CamPitchSpeed);
	CameraRotation.Pitch = Clamp(CameraRotation.Pitch, CamPitchBounds.Min, CamPitchBounds.Max);

	TempRot.Pitch = CameraDirection.Pitch + Clamp(GunRotation.Pitch - CameraDirection.Pitch, DT * -CamTrackPitchSpeed, DT * CamTrackPitchSpeed);
	if (FastTrace(Location + class'BUtil'.static.AlignedOffset(Rotation+TempRot, CameraOffset) + CameraElevation * vect(0,0,1), Location + CameraElevation * vect(0,0,1)))
	{
		CameraDirection = TempRot;
	}

	if (AIController(Controller) == None)
		Controller.SetRotation(CameraRotation + Rotation);
	// GunRotation must be sent from here for listenservers
	if (level.NetMode == NM_ListenServer)
		SendGunRotationToClients();
	// Server needs to know the new gunrotation
	else if (Role < ROLE_Authority && IsLocallyControlled())
	{
		log("UpdateRocketAcceleration, GunRotation:"@GunRotation);
		ServerTurretRotation(GunRotation);
	}
}

// Receive gun rotation from owning client server
function ServerTurretRotation(rotator NewGunRot)
{
	log("Server Turret Rotation");
	log("NewGunRot:"@NewGunRot);
	GunRotation = NewGunRot;

	// Send it on to the other clients
	SendGunRotationToClients();
	// Apply new gun rotation so local player can see it
	if (level.NetMode != NM_dedicatedServer && bDriving)
		UpdateSimulatedGunRotation();
}

Re: Rotation sent to server

Posted: Thu 08 Dec , 2011 9:08 pm
by Azarael
Splitting the Rotator into Pitch and Yaw sent as ints appears to make this work, so I'm guessing it was some kind of truncation issue, or sending structs in replication doesn't work well. The only problem now is in the initial weapon rotation.

Re: Rotation sent to server

Posted: Thu 08 Dec , 2011 10:23 pm
by iZumo
Rotator is compressed when replicated to a byte per each component. http://udn.epicgames.com/Three/Replicat ... l#Rotators

Use Quaternion, or as you did, split it into Pitch and Yaw (in this case we should call them Azimuth and Elevation). It's generaly unwise to use a similar structure to rotator, even thought the manual says so, as in UE2 modifying a structure will not be set internal dirty flag and if nothing else changes, the structure won't be send to the clients.