Match part of parent rotation to child rotation

I have a turret that is a child of a tank.

When the tank is on a flat surface and the turret aims at the target all goes well because the tank is on the horizon line, but as soon as it goes uphill or downhill or any other X or Z axis rotation its noticeable that the turret that is attached to it does not follow.

This turret is already rotating along its own Y axis to aim at the target, and thats working fine, but the problem is that the rotation along its X and Z rotations are always “zero”

This is because im using rotation instead of localRotation:

//Turret Head
RotationHeadHelper = Quaternion.LookRotation(TargetEnemy.transform.Find("TargetAim").position - TurretHead.transform.position, Vector3.up);
float rotationY = RotationHeadHelper.eulerAngles.y;
 float newYAngle = Mathf.MoveTowardsAngle(TurretCannon.transform.rotation.eulerAngles.y, rotationY, rotationSpeed * 10.0f * Time.deltaTime);
        
TurretHead.transform.rotation = Quaternion.AngleAxis(newYAngle,Vector3.up);

I cant figure out a way to make the turret to have the same X and Z rotation of its parent, the tank.

You could say that, If you visualize (like inside the editor) the XYZ gizmo on the turret, then pick the arrow point up, Y green arrow… the turret is always the same as the global Vector3.up, but the tank when going up or down on the terrain is obviously not…

I think the picture below will help make more sense

So… I know I have a few options but I do not know how to do it.
I know I can make the UP orientation of the turret to be the same as the tank(who is the parent)
I know also that I could convert the lookRotation from global to local somehow and then apply only the Y axis rotation

Well there must be loads of ways but I lost enough hair trying to figure this out, Im no good with 3D math, just the basics…
Any help much appreciated:p

Try to use transform.up instead of Vector3.up

Yep I tried that smurd

BTW there are 2 places that I use Vector3.up:

RotationHeadHelper = Quaternion.LookRotation(TargetEnemy.transform.Find("TargetAim").position - TurretHead.transform.position, Vector3.up);

and

TurretHead.transform.rotation = Quaternion.AngleAxis( newYAngle, Vector3.up);

I tryed both and it either doesnt change anything or breaks more.
But which one did you mean anyway?

Also can anyone tell me how to add rotations together?

I want to breakdown the rotations and add the parts together by each axis, i think that will fix it.

To explain better…
My turret Y axis rotation is fine, but the Z and X are not, I need to get the tank that the turret is attached to X and Z rotations and create a whole new euler rotation maybe

so I could do something like the pseudo code below:

newx = tank.transform.rotation.x
newz = tank.transform.rotation.z
newy = (I already have this value, see mt first post)

newRotation = (newx,newy,newz)

and in unity, using the Quaternion.Euler like this:

Vector3 newRotation = new Vector3(newXangle,newYAngle ,newZangle);
TurretHead.transform.rotation = Quaternion.Euler(newRotation);

But as I suspected, it doesnt work when the tank Z and X are different from the global right and forward and I think its because the Y angle that I get is from the Quaternion.LookRotation. But I think its weird, even as smurd pointed, I used my tank.transform.up and the problem is exactly the same.

Is Quaternion.LookRotation broken? how come using different up vectors dont change anything (and yea they are different cz I debugged my tank up and it does change)

Ok I almost got it, at least now the rotations from the turret head and the tank are veery close but its not 100%

GameObject myParent = transform.parent.root.gameObject; 
//Turret Head
Vector3 direction = TargetEnemy.transform.Find("TargetAim").position - TurretHead.transform.position;
direction.Normalize();
RotationHeadHelper = Quaternion.LookRotation(direction, TurretHead.transform.up);

HeadValuesHelper = new Vector3(
                                myParent.transform.rotation.eulerAngles.x,
                                Mathf.MoveTowardsAngle(TurretHead.transform.rotation.eulerAngles.y, RotationHeadHelper.eulerAngles.y, rotationSpeed * 10.0f * Time.deltaTime),
                                myParent.transform.rotation.eulerAngles.z
                              );
TurretHead.transform.rotation = Quaternion.AngleAxis(HeadValuesHelper.y, Vector3.up) * Quaternion.AngleAxis(HeadValuesHelper.x, Vector3.right) * Quaternion.AngleAxis(HeadValuesHelper.z, Vector3.forward);

Then I had an idea, to store the localRotation, after the global rotation has already been set, in a temporary variable then get the axis rotation that is corret (y axis) and set manually the other 2 to zero, this way the x and z local rotations would be zero (the same as the tank) and I would be able to just rotate the turret head to the correct value that I already have…

TurretHead.transform.localRotation = Quaternion.Euler(0, TurretHead.transform.localRotation.eulerAngles.y, 0);

All good in theory but it seems that the MoveTowardsAngle never reaches the goal value, so if I change the line above to the goal value directly it works, but I loose the easing/interpolation/tweening/whatever gradually increasing effect…

TurretHead.transform.localRotation = Quaternion.Euler(0, RotationHeadHelper.eulerAngles.y, 0);

This is an ungly way to do that, and obviously its not working as expected. Im sure there must be a way to do a lookrotation changing the localRotation directly.
Its really frustrating that the transform.localRotation.SetLookRotation does nothing, I tried the line of code below but nothing moved at all

Vector3 direction = TargetEnemy.transform.Find("TargetAim").position - TurretHead.transform.position;
TurretHead.transform.localRotation.SetLookRotation(direction, TurretHead.transform.up);