Get rotation of a randomly rotating turret on a moving tank (to Spawn missiles in that direction)

I’ve fried my brain with this one and would very much appreciate any help anyone can give! Looked at similar questions and answers but can’t get my head around these rotations…

I have a tank with a random rotation on its turret (it sweeps left and right, changing direction randomly).

I have a missile spawner as a child of the turret with a script which aims and fires along the axis of the turret:

In F3DMissileLauncherSimplified.cs, attached to the MissileLauncher child, I’m using the following code in the Fire() method (this is randomly triggered so that the missiles launch at varying intervals):

Transform barrel = transform.parent;
float turretRotation = barrel.parent.parent.parent.localRotation.eulerAngles.z;
Quaternion dirAngle = Quaternion.Euler(0, turretRotation, 0);
Transform tMissile = F3DPool.instance.Spawn(missilePrefab, barrel.position, dirAngle, null);

The Spawn method seems pretty standard and is defined as follows:

 public Transform Spawn(Transform obj, Vector3 pos, Quaternion rot, Transform parent)

The situation is slightly complicated by the fact that this is a Blender mesh imported with a 270 rotation on the x axis but all other transforms are aligned as you’d expect. (See screenshots above)

This all works fine when the tank is stationary but once I added a NavMeshAgent and a random roaming script, making the tank move around (in addition to the turret rotation) the missiles no longer come out in line with the turret, but off at varying angles.

I feel stupid. Surely getting the rotation angle, looking down a turret, can’t be this difficult!

Can’t seem to add a reply to @Scribe (too many replies on the same post?) but this is definitely his answer. Works great. Thank you! I’d obviously been over-thinking this, being still relatively new to Unity.

So based on his reply, the solution is:

Transform barrel = transform.parent;
Quaternion dirAngle = Quaternion.LookRotation(-transform.up, transform.forward);
Transform tMissile = F3DPool.instance.Spawn(missilePrefab, barrel.position, dirAngle, null);

For anyone interested, checking LookRotation in the docs, explains the solution. This is how to get the angle in the direction I want:

     Quaternion LookRotation(Vector3 forward, Vector3 upwards);

and because the gameobject to which the script is attached (the MissileLauncher) has an odd rotation the LookRotation is adjusted accordingly:

‘Forward’ is actually the reverse of the object’s y axis (-transform.up) which is green
‘Up’ is my object’s forward axis (positive z) the arrow in blue.

Comparing the object’s axis with the world axis explains why things have to be adjusted. To get the ‘forward’ parameter of the LookRotation function you have to go along the object’ Y axis (in reverse) To get the ‘up’ parameter you have to go along my object’s z axis.

Thank you for pointing that out. I hope this helps other newbies flummoxed by all these rotations and axis!

This is easy if your firing script is under the barrel and not the tank!

  // C# - Called by Update() on the Barrel
  void Fire(){
    // Find out what the barrel thinks forward is.
    Vector3 direction = transform.TransformDirection(Vector3.forward * 1f);
    
    // Spawn the bullet at our position + direction + rotation
    GameObject bullet = Instantiate(bulletPrefab, transform.position + direction, transform.rotation);
    
    // Send the bullet speeding off "forward" (this only works because we rotated the object when we created it.)
    bullet.GetComponent<Rigidbody>().velocity = new Vector3(1f, 0, 0);
    
    // Do your Spawn or Network.Spawn now that it's ready.
  }