- Home /
Angle of object relative to transform of second object
Hi gang!
Working on a ship game, could really appreciate a pointer on this.
Trying to find the angle of object B (image below) in relation to object A, regardless of object A's rotation. Essentially, a side-wise LookAt reading.
In effect, finding Ship B's angle in relation to Ship A's position is so it can turn it's closes left or right side (and rain fiery justice).
Tried:
RayCast - great for firing, but not to anticipate the positioning beforehand.
Quaternion.Angle - perfect, except it is considering the other object's rotation.
Vector3.Angle - doesn't consider the individual rotations, only positions.
Any pointers would be much appreciated, thanks in advance!
Answer by mpavlinsky · Jan 04, 2012 at 07:52 PM
So if I understand correctly you want Ship B to face it's side towards Ship A. You can achieve this with a little linear algebra to find the at vector you would like and then just use Quaternion.SetLookRotation(). I made a brief script to demonstrate:
using UnityEngine;
using System.Collections;
public class ShipTest : MonoBehaviour {
// Set me to the object you want however you see fit.
public GameObject targetObject = null;
// Update is called once per frame
void FixedUpdate () {
// Subtract the positions to find the vector from our object to the target.
Vector3 toTarget = targetObject.transform.position - transform.position;
toTarget.Normalize();
// Find the vector perpendicular to the 'up' and 'right' (in this case the vector to the target object) vector to find the new 'at'.
Vector3 newAt = Vector3.Cross(transform.up, toTarget);
// Make new rotation.
Quaternion newRotation = new Quaternion();
newRotation.SetLookRotation(newAt);
transform.rotation = newRotation;
}
}
Thanks mpavlinsky!
I used your method and it worked, did one for the other side, but the challenge was detecting which side was closer. SetLookRotation was also a bit too precise for my liking. I ended up using a different code I'll post below, but yours got me in the right direction; much appreciated!
Answer by VladN · Jan 05, 2012 at 03:34 AM
In the end used the 360 angle trick mentioned here along with some of the suggestions above:
//subtract positions to find the vector to target
var toTarget : Vector3 = target.transform.position - transform.position;
//360 angle from object (runs ContAngle function which in turn runs AngleDir
var attackAngle = ContAngle(transform.forward, toTarget, transform.up);
//distance to target
var shipDistance = Vector3.Distance(transform.position, target.transform.position);
//if ship is within range (I use 8 for testing)
if(shipDistance <= 8){
//turn left/right side, depending on which one is closer
if(attackAngle >=0 && attackAngle <90 || attackAngle >=180 && attackAngle <270){
transform.Rotate(0, -1*Time.deltaTime*rotationSpeed,0);
}
if(attackAngle >90 && attackAngle <180 || attackAngle <=360){
transform.Rotate(0, 1*Time.deltaTime*rotationSpeed,0);
}
}
//if ship is not in range
if(shipDistance >8){
//slowly rotate to face/chase target
neededRotation = Quaternion.LookRotation(target.transform.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, neededRotation, Time.deltaTime*rotationSpeed/35);
}