- Home /
solved in comments
Quaternions, relative clamped rotation, look rotations in spaceship movement
I've come up against my limited knowledge of Quaternions, and I've almost solved the problem, but not quite.
In the code below, the pitch and roll of a ship work exactly as expected, EXCEPT that when rotation a "direction" transform that determines the forward direction of the ship, the rotations are then additive, so rotating the "direction" of travel 90 degrees yields a 180 degree rotation in the ship.
The ship must be constrained to one direction of travel, as if it were in a tunnel. the tunnels may change direction, but the ship's rotation must remain relative to the tunnel's main direction.
Here's the code below. It all works as I want, except for additive rotations between direction and final forward direction of the ship:
Thanks in advance!
using UnityEngine;
using System.Collections;
public class QuatTest : MonoBehaviour {
public Transform direction;
public float roll;
public float rollSpeed;
public float pitch;
public float rotationSpeed;
protected Transform trans;
public Transform container;
protected Quaternion rollQuat = Quaternion.identity;
protected Vector3 travelDir;
void Start ()
{
trans = transform;
container = trans.parent;
}
void Update ()
{
container.rotation = direction.rotation;
travelDir = container.forward;
Rotation();
roll += rollSpeed;
roll = Mathf.Repeat(roll, 360);
Debug.DrawRay(trans.position, trans.forward * 10f, Color.green);
Debug.DrawRay(trans.position, travelDir * 10f, Color.white);
Debug.DrawRay(trans.position, trans.right * 10f, Color.red);
}
protected void Rotation()
{
//this line ALMOST acts as desired:
// without LookRotation, AngleAxis yields completely wrong angles and ship rotates wildly
// with LookRotation as is, rotation "direction" transform creates an ADDITIVE rotation between the two,
// so rotating the "direction" transform 90 degrees yields a 180 degree rotation in the ship, BUT
// the pitch and roll then behaves as expected on the resultant travelDir and trans.right vectors
// i've tried replacing travelDir with trans.forward, and this yields the same result
rollQuat = Quaternion.AngleAxis(roll, travelDir) * Quaternion.LookRotation(travelDir);
trans.rotation = Quaternion.Lerp(
trans.rotation,
Quaternion.AngleAxis(pitch, trans.right) * Quaternion.LookRotation(travelDir) * rollQuat,
Time.fixedDeltaTime * rotationSpeed);
}
}
im not quite understanding are you saying when you pitch 90 degrees to aim at the ground you end up with 180 pitch ins$$anonymous$$d?
also I feel like lookrotation should be
Lookrotation(travelDir, ...) with ... being maybe container.up or transform.up i'm not sure
what is it exactly that you want to do?
Cause I also feel like what your wanting to do is
take the current rotation add to it the pitch and the roll required
but if thats the case then replace quat.look with the ships current rotation so
trans.rotation rollquat pitchquat;
Of course I think if you do a look direction in the ships forward AND use the ships up (so lookrotaiotn(travelDir,trans.forward) you end up with the ships rotation as it is.
well, pitch and roll are working currently, and they work properly to the ship's rotation. however, that only works if the
Vector3 travelDirection (deter$$anonymous$$ed by public Transform direction.rotation)
is Vector3.zero.
In order to overcome that and make pitch and roll relative, I am trying to use "travelDirection" as a "forward" axis to orient the rotations. but, because of the additive nature of the rollQuat Quaternion specifically, when I rotate the "forward" axis travelDirection 90 degrees, the ship turns 180.
In its new 180 degree orientation, the roll and pitch work exactly as I desire, but the ship is just facing the wrong way. I have tried various combinations of LookDirection(), AngleAxis(), and other quaternion functions. this is the closest I've come, except for the pesky wrong orientation.
I will try adding the ship's current to roll and pitch, although I think I tried that many iterations ago. I've changed it so many times now that I can't quite remember what I"ve tried and what I haven't. :0
using this line:
rollQuat = Quaternion.AngleAxis(roll, travelDir) * Quaternion.LookRotation(travelDir);
trans.rotation = rollQuat * Quaternion.AngleAxis(pitch, trans.right) * Quaternion.LookRotation(travelDir);
yields the same behavior. if I reorient the "direction" transform, the ship rotates twice as far.
oh man, i realized i had AngleAxis in the logic twice, which was obviously the problem.
i've been looking at this problem way too long. if you want to put your comment as an answer, i'll gladly accept it.
thanks for the extra set of eyes on the problem!