- Home /
AI Aircraft/Spacecraft yaw and pitch help
I'm guessing this question has been asked to death, but I'm more looking for how to implement this into my AI code, since right now all they do it just rotate on the y axis and just spin around the enemy in a RotateAround type effect, which doesn't look very exciting.
I can easily make aircraft/spacecraft turn on yaw and pitch very easily using the input function and I understand how it works since you use transform.Rotate, but how do I get an AI to do it? I've tried manipulating the LookAt function and turning off the y axis and doing this as well for transform.Rotate but this just gave some very jerky effects and didn't bank the spacecraft at all to turn it. I've thought of using relativetorque but I'd rather someone clarify how to go about it, either with pseudoscript or a snippet of code that I could work with, or even just a general explanation.
If this is sounding confusing, then think of it in old Elite style controls, left/right to bank left and right and up/down to pitch up and down, to turn you would bank a bit, then climb or dive, that is the effect i'm looking for.
But i'm a little stumped as to how to get the AI to do it, I'll provide a snippet of code that can be used since it is repeated in my code for other behaviours, also it's using a rigidbody system, so it is already moving forward in the fixedupdate() function using AddForce
function Patrol ()
{
CanSelectNewWaypoint = false;
//var RandomWaypoint : int = Random.Range(0, PatrolRoute.Length);
if (Vector3.Distance(PatrolRoute[WaypointNumber].position, transform.position) < 50)
{
WaypointNumber++;
if (WaypointNumber >= PatrolRoute.Length)
{
WaypointNumber = 0;
}
}
WaypointTarget = PatrolRoute[WaypointNumber].transform;
var Rotation = transform.rotation;
var Position = WaypointTarget.position - transform.position;
transform.LookAt(WaypointTarget.position);
transform.rotation = Quaternion.Slerp(Rotation, transform.rotation, 2.0* Time.deltaTime);
//transform.Rotate (-Angle * 0.1, 0, -Angle * 0.1);
//yield WaitForSeconds (TimeUntilNewWaypoint);
CanSelectNewWaypoint = true;
}
Well if you are using AddForce then it will be kind of difficult to do the Elite style controls for an AI, because of trying to workout what force to apply to get to the way point.
Tilting the craft without engine impulse causes an aspect change, but not a velocity change (because there's no air resistance or lift), so changing direction involves changing the aspect, firing the main engines in that aspect which causes the craft to change its direction of travel toward that of the orientation at a rate derived from the current velocity and the power of the engines. It's certainly possible - but damn hard - to work out what those would be for an AI (and obviously there are an infinite number of possibilities of potential actions).
Aircraft work differently due to the areas of high and low pressure caused across the rudder and wings.
So it might work if you Slerp / Damp the direction of travel towards the target point and then adjust the pitch and yaw to account for the rate of change (e.g. when climbing, a plane is angled more nose upwards than the line which describes its actual ascent).
I guess the question is - do you really want an AI to be able to calculate the forces - in which case probably a genetic algorithm or neural network would be the best way of making it seem realistic - or can you just "simulate" it.
It's always struck me that you'd be much better off with maneuvering thrusters on a spacecraft that are capable of turning the craft around it's local Y axis - however I guess that Elite/Braben took the view that these would have to be extremely powerful to compete with the main engines while rotating around the local Z forward direction would require little power given that it is not in any way opposing the main engines.
I did have a thought of using vector3.angle to deter$$anonymous$$e which direction to go in using transform.rotate for the x and z axis to rotate toward the other object until the position vector is zero, when that happens it flies in a straight line towards the target. Could that work?
I would:
Deter$$anonymous$$e the angle to the waypoint
currentRotation = Quaternion.Slerp(currentRotation, targetRotation, Time.deltaTime * smoothing);
movementDirection = currentRotation * Vector3.forward;
$$anonymous$$ove in that direction and then set the orientation of the rotation of the craft based on how much different the current direction is from the desired direction
var currentDirection = currentRotation Vector3.forward; var targetDirection = targetRotation Vector3.forward; transform.rotation = Quaternion.AngleAxis(Vector3.Angle(currentDirection, targetDirection) * extraSteeringFactor, Vector3.Cross(currentDirection, targetDirection));
No they are not fixed to a set altitude, they can fly anywhere they want to in all three dimensions, the thing that i'm trying to avoid are the spacecraft circling each other on the y axis while facing each other, although LookAt is veru handy, it also makes my game look a bit "boring" as they are not flying around trying to outflank or get behind each other.
This is why I was looking at using Vector3.Angle as a possible solution and setting it so that if the angle to the target is 0, then fly straight at the target, if the angle to the target is greater than 0 but less than 180 on the x axis then roll right on the x axis and if the angle to the target is greater than 0 but less than 180 on the z axis then roll on the Z axis. The target vector will still be found in x, y and z axes though.
The addforce on vector3.forward that already exists on the craft will give it the momentum to begin turning.
I hope this clears things up a bit
Answer by Supershandy · Apr 14, 2013 at 05:21 PM
I think I may have found the answer, it has taken me a while and involved opening a new project with just a simple cube and sphere, but it's doing what I wanted it to do which was to rotate only on two axes, z and x.
It doesn't look like it follows the target exactly and it seems that there might be some work to do, though if i'm honest i'm a little scared to touch the code now.
Anyway, all I did was to use the Quaternion.LookRotation to look at the target and then set a vector3 direction, after that, I just tried locking off angles until I got what I was looking for, in this case it was locking off the y angle on the roll and the x on the pitch.
var RollAngle = Quaternion.LookRotation (TargetDirection, Vector3.forward);
RollAngle.y = 0;
var PitchAngle = Quaternion.LookRotation (TargetDirection, Vector3.forward);
PitchAngle.x = 0;
transform.rotation = Quaternion.Slerp(transform.rotation, PitchAngle, Time.deltaTime * 2.5f);
transform.rotation = Quaternion.Slerp(transform.rotation, RollAngle, Time.deltaTime * 2.5f);
If anyone can refine the code please feel free to let me know, but for now, my nightmare is somewhat over
Hi Supershandy, I am actually also struggling, trying to implement roll and pitch movements for an AI. Unfortunately, my nightmare doesn't seem to be close from an ending.
I would be really interested if you could share some insights, especially if you refined the code since then!
Your answer
Follow this Question
Related Questions
AI Turret Aiming 2 Answers
One player tag, two players, enemy attack who ever is closer? 1 Answer
Enable Phyics between CC and RB 0 Answers
Steering using Quarternion.LookRotation. 0 Answers
AI script not using gravity 1 Answer