How can I make the airplane AI lean into the turn when it is turning?

How can I make an airplane AI lean into the turn when it is turning? Right now it just looks at a random waypoint every 1 second but when it turns it doesn’t lean into it. How could I do that?

bump

bump

when it turns don’t make it turn with yaw make it roll and go “up” when it is lined up with the waypoint. Either that or I am guessing you are changing the y rotation, you could also change the z rotation of the plane.

in order to be able to make it lean and such first you have to figure out how your AI is rotating, like are you using a lerp or slerp function? and such. and depending if it’s a rigidbody movement or what not you can always try making a function for the rotations.
and sometimes depending if it’s a short turn it might lean anyways, so you might want to figure out when to lean.

now i can’t really give you an idea of how to code it, unless i see some code of what’s going on. maybe make a youtube video? so we can see visually what’s going on?

It is using a rigidbody. I was thinking of having it measure how close it is to being 0 degrees away from looking at it, then having it turn on its z to lean in based on that amount, but i don’t know how to do that.

Here is the code that I have so far:

The rotation stuff is under the “if (target)” in the FixedUpdate.

#pragma strict

var Target : Transform;
var Waypoints : GameObject[];

var IsPatrolling = false;
var IsChasing = false;

var TurnDamping : float;
var ChaseDamping : float;
var PatrolDamping : float;
var Speed : float;

var CanSelectNewWaypoint = true;
var TimeUntilNewWaypoint : float;

var ChaseRange : float;
var ChaseTimeMin : float;
var ChaseTimeMax : float;

function Awake () {

	Waypoints = GameObject.FindGameObjectsWithTag("AirplaneWaypoint");
}

function FixedUpdate () {

	rigidbody.AddForce (transform.forward * Speed);
	
	var hit : RaycastHit;
	var direction = transform.TransformDirection(Vector3.forward);
	
	
	
	if (Physics.Raycast (transform.position, direction, hit, ChaseRange)) {
		Debug.DrawLine (transform.position, hit.point, Color.cyan);
		
		if (hit.collider.gameObject.tag == "JetAI") {
			Target = hit.transform;
			IsChasing = true;
			IsPatrolling = false;
			Chase();
			TurnDamping = ChaseDamping;
			}
	}
	
	if (IsPatrolling == true  CanSelectNewWaypoint == true) {
		TurnDamping = PatrolDamping;
		Patrol();
		}
	
	if (Target) {
		var rotation = Quaternion.LookRotation(Target.position - transform.position);
		transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * TurnDamping);
	}
	
}

function Patrol () {

	CanSelectNewWaypoint = false;
	var RandomWaypoint : int = Random.Range (0, Waypoints.Length);
	Target = Waypoints[RandomWaypoint].transform;
	yield WaitForSeconds (TimeUntilNewWaypoint);
	CanSelectNewWaypoint = true;
	
}

function Chase () {

	transform.eulerAngles.z = Target.eulerAngles.z;
}

So, everything that you want to figure out is located here:

    if (Target) {
        var rotation = Quaternion.LookRotation(Target.position - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * TurnDamping);
    }

So first, you want to know the angle between the two rotations:

var angle = Quaternion.Angle(transform.rotation, rotation);

Then you want to know if the target is left or right:

var direction = transform.InverseTransformPoint(target.position).x > 0 ? 1.0 : -1.0; // right is 1, left is -1

Then you simply do some math…

var z = angle * direction * modifier; // modifier should be like 0.15 or so
transform.Rotate(0,0,z);

Is there a better way to do this, maybe with an Slerp or something? They way you did was really twitchy. It worked but it looked like it was trying to decide between -1 and 1 a lot.

Hmmm… when I used it was is real smooth.

You could swap Quaternion.Angle for Vector3.Angle:

var rotation = transform.rotation;
var pos : Vector3 = transform.InverseTransformPoint(target.position);
var dir : float = pos.x > 0 ? 1.0 : -1.0;
var angle = Vector3.Angle(Vector3.forward, pos) * dir;
transform.LookAt(target.position);
transform.rotation = Quaternion.Slerp(rotation, transform.rotation, 2.0 * Time.deltaTime);
transform.Rotate(0,0,-angle * 0.1);

Well, that does work better, but it still has a few problems. Since turning the z axis is affecting the other axis’s rotations (btw why is that) If i set the damping on the turning below 1 (which is where i need it at about 0.2), it can’t turn on the Y axis fast enough and it just crashes into the ground. Would it make a difference to just have the localRotation.z = a ceratian value, instead of rotating it based on a rotation force?

bump

bump

Maybe this will help ?