- 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!
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                