- Home /
Mimic other object's rotation on one axis (with offset)
So, I have an object which is a ship and the other object which is its external "helper" axis for the ship's animations to be possible. What I'm trying to do is to have:
the external axis to inherit x-axis rotation from the ship's x-axis rotation
the ship to inherit y-axis rotation from the external axis's y-axis
and ship's z-axis to inherit the z-axis rotation from external axis while offseting it for banking purposes (as befits for an anti-grav ship)
and the problem I have is that in some cases a gimbal lock occurs on the z-axis (because here I'm using Quaternion.eulerAngles to offset the rotation on z-axis for banking), I know quaternions is the solution here but I have no idea how to implement it and Quaternion.eulerAngles seem to be exactly the same as localEulerAngles. Since my ship can fly on up-side down surfaces or perpendicullary to World's up axis the gimbal lock is unavoidable.
Here's some of my code as image with some red guides: http://prntscr.com/4esc03
Whole function's code:
// Turning controls
@HideInInspector var HorizAxisInputVar : float;
private var HorizAxisInputLerpSpeed: float;
private var HorizAxisInputVarSmooth : float;
private var HorizBankVar : float;
private var AirBreaksAdd : float;
private var AirbreaksBank : float;
private var airbrakesRotation : Vector2;
private var turningSpeed : float;
function ShipTurning (){
// Simulate axis for smooth analog and keyboard input
var axisLerpSpeed : float = 10;
var maxAxisLerpSpeed : float = 0;
if (USER != PL || USER == "Autopilot")
axisLerpSpeed = 20;
if (Mathf.Abs(HorizAxisInput) > 0.1)
maxAxisLerpSpeed = 8;
HorizAxisInputLerpSpeed = Mathf.MoveTowards (HorizAxisInputLerpSpeed, maxAxisLerpSpeed, Time.fixedDeltaTime * axisLerpSpeed * 2);
if (HorizAxisInput > 0.05 || HorizAxisInput < -0.05){
HorizAxisInputVar = Mathf.MoveTowards (HorizAxisInputVar, HorizAxisInput, Time.fixedDeltaTime * HorizAxisInputLerpSpeed);
} else {HorizAxisInputVar = Mathf.MoveTowards (HorizAxisInputVar, 0, Time.fixedDeltaTime * axisLerpSpeed);}
// Analog input variable
HorizAxisInputVar = Mathf.Clamp (HorizAxisInputVar, -1, 1);
HorizAxisInputVarSmooth = Mathf.Lerp (HorizAxisInputVarSmooth, HorizAxisInputVar, Time.fixedDeltaTime * (axisLerpSpeed-1));
if (USER != PL || USER == "Autopilot")
HorizAxisInputVarSmooth = HorizAxisInputVar;
turningSpeed = ((HorizAxisInputVarSmooth * Handling) + AirBreaksAdd) * Time.fixedDeltaTime;
// Ship banking
var bankAngle : float;
if (!BRTotalRotation || BRTotalRotation == 360){
HorizBankVar = Mathf.Lerp(HorizBankVar, HorizAxisInputVarSmooth, Time.fixedDeltaTime * 2);
if (!BRTotalRotation)
bankAngle = (-HorizBankVar * 35) + AirbreaksBank + shipStandbyAnimation.z;
}
// Axises rotations
if (ShipOnMagStrip){
PlayerShipExternalAxis.Rotate(
-Vector3.Dot(myTransform.forward, PlayerShipExternalAxis.up) * 45,
turningSpeed,
0
);
myTransform.Rotate(0, -Vector3.Dot(PlayerShipExternalAxis.forward, -myTransform.right) * 10, 0);
/*myTransform.Rotate(
myTransform.up * Mathf.Sign(-Vector3.Dot(PlayerShipExternalAxis.forward, -myTransform.right)) *
Quaternion.Angle(myTransform.rotation, PlayerShipExternalAxis.rotation)
);*/
/*myTransform.rotation = Quaternion.LookRotation(
PlayerShipExternalAxis.forward,
myTransform.up);*/
// myTransform.Rotate(0, -Vector3.Dot(PlayerShipExternalAxis.forward, -myTransform.right) * 45, 0);
myTransform.rotation.eulerAngles.z = PlayerShipExternalAxis.rotation.eulerAngles.z + bankAngle;
} else {
PlayerShipExternalAxis.localEulerAngles.x = myTransform.localEulerAngles.x;
PlayerShipExternalAxis.localEulerAngles.y += turningSpeed;
myTransform.localEulerAngles.y = PlayerShipExternalAxis.localEulerAngles.y;
if (BRTotalRotation == 0)
myTransform.rotation.eulerAngles.z = PlayerShipExternalAxis.rotation.eulerAngles.z;
}
// Control additional axis for parallel ship rotation
if (AGRayHitDistance <= shipInAirLimit)
AdditionalAxis.localEulerAngles.z = myTransform.localEulerAngles.z;
// Ship inAir momentum variable
if (AGRayHitDistance > shipInAirLimit){
OffGroundRotationChange += turningSpeed;
} else OffGroundRotationChange = 0;
}
Any help is appreciated!