I'm developing a 3D spacegame where the camera is in a constant 2D (top down) state. I am able to fire a projectile of speed (s) at a target moving at a given velocity and hit it every time. Great! Okay so what if that target has an angular velocity around a parent? I noticed that if the target has a parent object that is rotating, my projection isn't correct since it doesn't account for the angular velocity.
My initial code was built around the assumption that:
Position_target + Velocity_target * t = Position_shooter + Velocity_shooter * t + Bulletspeed * t
I assume that the shooter is stationary (or potentially moving) and needs to fire a bullet with a constant magnitude.
I simplify the above to this
Delta_Position = Position_target - Position_shooter
Delta_Velocity = Velocity_target - Velocity_shooter
Delta_Position + Delta_Velocity * t = BulletSpeed * t
Squaring both sides I come to a quadratic equation where I can solve for t given determinant outcomes or zeros. This works perfect. I return a t value and then project the target's position and current velocity out to that t, and then I have turret scripts that rotate at a given angular velocity towards that point. If the turret says its looking at that point within 1% on all axis, it fires the bullet at speed(s) and its a 100% hit if the target doesn't alter its course or velocity.
I started adding components on my ships / asteroids that were a child of the parent object, like a turret attached to a ship where the turret itself is a target. If the ship is rotating around an axis (for example Y axis) and the turret is not at x=0 and z=0 my projection no longer works. I thought that using r * sin ( theta + omega * t) as the angular velocity component for the X position and r * cos ( theta + omega * t) for the Z position could work. Theta is the current rotation (with respect to world coordinates) and the omega is the eulerAngle rotation around the y axis.
I've quickly realized this only works with rotating around the y axis, and I can't put the sin into a quadratic equation because I can't extract the t from it so I can't really project this appropriately. I tried using hyperbolics but it was the same situation. I can create an arbitrary t, let's say t=2, and calculate where the object will be in 2 seconds. But I am struggling to find a way to implement the bullet speed projection with this.
Position_targetparent + Velocity_targetparent * t + [ANGULAR VELOCITY COMPONENT] = Position_shooter + Velocity_shooter * t + Bulletspeed * t
Delta_Position_X + Delta_Velocity_X * t + S * t = r * sin (theta + Omegay * t)
Delta_Position_Z + Delta_Velocity_Z * t + S * t = r * cos (theta + Omegay * t)
From here I have been spinning my wheels endlessly trying to figure out a workable solution for this. I am using the eulerAngle.y for the omega which works well. Ultimately I just need that instantaneous point in space that I should fire at which is a product of the speed of the bullet and the distance of the projection, and then my turrets aiming scripts will take care of the rest.
I have been looking at a spherical coordinate system based around the parents position (the center of the rotation)
Vector3 deltaPosition = target.transform.position - target.transform.root.position;
r = deltaPosition .magnitude;
float theta = Mathf.Acos(deltaPosition.z / r);
float phi = Mathf.Atan2(deltaPosition.y,deltaPosition.x);
float xPos = r * Mathf.Sin(theta) * Mathf.Cos(phi)
float yPos = r * Mathf.Sin(theta) * Mathf.Sin(phi)
float zPos = r * Mathf.Cos(theta)
Vector3 currentRotation = transform.root.gameObject.transform.rotation.eulerAngles * Mathf.Deg2Rad;
Vector3 angularVelocity = transform.root.gameObject.GetComponent<Rigidbody>().angularVelocity;
I can calculate the position of the object given these angles ... but I am struggling to turn this into something I can use with the omega * t (angular velocity) approach.
I am wondering if there is a more elegant approach to this problem, or if someone can point me in the right direction of a formula to help me think this through? I am not the best with Quaternions and EulerAngles but I am learning them slowly. Maybe there's something clever I can do with those?