Hey, I am having a problem with a 2d (air)plane I am working on. It is a side scrolling game, and I want the plane to follow the player. To move I am using the rigidbody2D and to rotate I am using Quaternion LookAt. The problem is, when the aircraft exceeds the X position of the player, it goes in the opposite direction, so it’s moving away from the player instead of towards it. When it gets behind the player again ( X<=player X), it follows the player normally.
I want the aircraft to rotate with a rotatespeed, so it won’t instantly face the player, and has to make a nice loop when it needs to.
Can anyone help me with this? I’ve looked into multiple solutions, but haven’t found anything.
Okay, so this is a little ‘hacky’ in that I create a new parent so that I can separate the rotation around z and the local rotation around x (to make the plane upright). There would be a way of doing this without the extra parent, but I should be wrapping presents and not spending hours on Quaternion rotations!
The following should be attached to the highest object in your plane object hierarchy:
public float forwardSpeed = 5;
public float turnSpeed = 90;
public float twistSpeed = 180;
public Transform target;
Vector3 targetPos;
Transform this_transform;
Vector3 dir;
Transform parentT;
GameObject parentGO;
void Start(){
this_transform = transform;
parentGO = new GameObject("rotationControl");
parentT = parentGO.transform;
parentT.position = this_transform.position;
this_transform.parent = parentT;
}
void FixedUpdate(){
dir = new Vector3(target.position.x - parentT.position.x, target.position.y - parentT.position.y, 0);
//Look rotation (around Z axis)
Quaternion q = Quaternion.FromToRotation(Vector3.right, dir);
parentT.rotation = Quaternion.RotateTowards(parentT.rotation, q, turnSpeed*Time.deltaTime);
//Twist rotation (around local X axis)
Quaternion q2 = Quaternion.identity;
if(Mathf.Sign(dir.x) < 0){
q2 = Quaternion.Euler(180, 0, 0);
}
this_transform.localRotation = Quaternion.RotateTowards(this_transform.localRotation, q2, twistSpeed*Time.deltaTime);
//Movement (you can use your forces here, this was mainly for testing)
parentT.position += parentT.right*Time.deltaTime*forwardSpeed;
}
This should turn the plane to face the target over time and upright the plane when it becomes upside-down, hopefully without causing any movement in the z axis (you may want to clamp the z value just to be safe)!