Spiraling into Oblivion

I’m trying to set up an AI that strafes around a target point. So far, I have everything working fantastically when the object is strafing perfectly on the plane of the X axis. However, the setting is within 3d-space, so I’ve implemented the ability to barrel roll around the Z axis as well. Whenever there is the slightest abberation around the Z axis, the object does what I’ve come to call “spiraling into oblivion,” where they slowly spin in smaller and smaller circles until they are spinning out of control around the Y axis, essentially freaking out. I’ve tried several different ways to implement the spinning, but can’t find a way. Any other Unity pros out there have an idea how to overcome this?

var goRight = false;
var goRollLeft = false;
var goRollRight = false;
var rolling = 0.0;
var thrust = 5;
var lookTarget : Transform;
var lastTime = 0.0;

function Update () 
{
	if(goForward)
	{
		transform.parent.Translate(Vector3.forward * thrust * Time.deltaTime);
	//	lookTarget.Translate(Vector3.forward * thrust * Time.deltaTime);
	}
		
	if(goBack)
	{
		transform.parent.Translate(Vector3.forward * thrust * -1 * Time.deltaTime);
	//	lookTarget.Translate(Vector3.forward * thrust * -1 * Time.deltaTime);
	}
	
	if(goLeft)
	{
		transform.parent.Translate(Vector3.right * thrust * -1 * Time.deltaTime);
	//	transform.parent.RotateAround(lookTarget.position,transform.parent.up,thrust * Time.deltaTime * -1 * 10);
	}
	
	if(goRight)
	{
		transform.parent.Translate(Vector3.right * thrust * Time.deltaTime);
	//	transform.parent.RotateAround(lookTarget.position,transform.parent.up,thrust * Time.deltaTime * 10);
	}
	
	if(goRollRight)
	{
		rolling -= thrust * Time.deltaTime * 4;
	//	transform.parent.Rotate(Vector3.forward * thrust * -1 * Time.deltaTime * 4);
	}
		
	if(goRollLeft)
	{
		rolling += thrust * Time.deltaTime * 4;
	//	transform.parent.Rotate(Vector3.forward * thrust * Time.deltaTime * 4);
	}
		
	//transform.parent.LookAt(Vector3.Lerp(transform.parent.position, lookTarget.position, Time.deltaTime));
	//transform.parent.LookAt(lookTarget.position);
	transform.parent.rotation = Quaternion.Slerp(transform.parent.rotation, Quaternion.LookRotation(lookTarget.position - transform.parent.position),Time.deltaTime * thrust);
	transform.parent.eulerAngles.z = rolling;
}

If you are doing orbital strafing, it is best to handle the rotation by using transform.LookAt on the target point (it’s a bit less code than Quaternion.LookRotation). If you do this each frame before the sideways movement, you should get a stable orbit. The method you are currently using is a reasonable way to smooth the end of a rotation but it isn’t accurate enough for the kind of thing you are doing here.

I gave that a shot, putting the LookAt before the sideways movement. It still works great as log as it’s on the same level as what it’s orbiting around. However, when moving the target, it seems that it is constraining it’s movements to a particular sphere, and instead of moving left-right around the target, it’s moving east-west around the target. Such that when it gets around either the northern or southern pole of the area, left and right mean nothing and it’s still constantly spinning in space.

If i take out the rolling around the z axis it doesn’t ever run into the problem, however it also doesn’t have the opportunity, as it can only sit there on the same plane the lookTarget.