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 ?