Change transform.forward while slerping rotations around the transform.forward axis

Pretty new to Unity and 3d game development, so I am probably not asking the question correctly, but here goes…

I am working on a space RTS game which uses UnitySteer (GitHub - ricardojmendez/UnitySteer: Steering, obstacle avoidance and path following behaviors for the Unity Game Engine) to move units. In general it works pretty well and gives some really cool looking behavior. However, there is a deal breaking issue I am running into. Units, somewhat randomly, rotate around their forward axis/vector (not sure I am getting the terminology correct). That is to say the units are heading in the right direction in world space, and their engines and cockpits have the correct orientation, but they are spinning like a top around the axis that runs from engine to cockpit.

I have been digging through the source code and found this snippet that sets a unit’s forward vector:


    /// <summary>
	/// Turns the vehicle towards his velocity vector. Previously called
	/// LookTowardsVelocity.
	/// </summary>
	protected void AdjustOrientation(float deltaTime)
	{
		/* 
		 * Avoid adjusting if we aren't applying any velocity. We also
		 * disregard very small velocities, to avoid jittery movement on
		 * rounding errors.
		 */
 		if (DesiredSpeed > MinSpeedForTurning && Velocity != Vector3.zero)
		{
			var newForward = OrientationVelocity;
			if (IsPlanar)
			{
				newForward.y = 0;
			}

			if (TurnTime > 0)
			{
				newForward = Vector3.Slerp(Transform.forward, newForward, deltaTime / TurnTime);
			}
			Transform.forward = newForward;
		}
	}

While I suspect there might be an issue with how the OrientationVelocity is set in code further upstream, I thought I would focus on the AdjustOrientation method for now.

What I would like to accomplish is to still get the units to correctly orient themselves, but drastically reduce the speed at which they rotate around their local forward vector. Ideally I would love an auto-level algorithm but that is probably outside the scope of this question.

I have taken a couple stabs at reducing the rotation speed, but it always affected their overall movement and not just the rotation along that one vector.

In context (i.e. playing with the app so you can see what what effect your changes are making), these problems usually can be figured out fairly quickly. Out of context with just a snipped of the code that may or may not be the real problem, getting to a solution is problematic. Note I don’t believe the code ‘as is’ will not compile because it uses ‘Transform’ with an upper case ‘T’ rather than ‘transform’.

As a shot in the dark, here is something for you to try. The ‘Vector3.up’ is the LookRotation() can be change for your situation. For example, you may want ‘transform.up’ instead.

protected void AdjustOrientation(float deltaTime)
	{
		/* 
        * Avoid adjusting if we aren't applying any velocity. We also
        * disregard very small velocities, to avoid jittery movement on
        * rounding errors.
        */
		if (DesiredSpeed > MinSpeedForTurning && Velocity != Vector3.zero)
		{
			var newForward = OrientationVelocity;
			if (IsPlanar)
			{
				newForward.y = 0;
			}

			Quaternion q = Quaternion.LookRotation (newForward, Vector3.up);
			if (TurnTime > 0)
			{
				transform.rotation = Quaternion.Slerp(transform.rotation, q, deltaTime / TurnTime);
			}
			else {
				transform.rotation = q;
			}
		}
	}
}