- Home /
[c#]How to check if an object is facing another?
Hi all! So i`m making a 2d shooter and making an enemy that will dodge bullets,
Enemy is following player, but if player faces enemy,it changes movement.Thanks!
void Update ()
{
player = GameObject.FindGameObjectWithTag("Player");
if(player !=null)
{
transform.LookAt(player.transform.position,Vector3.forward);
transform.Translate(Vector3.forward * Time.deltaTime * speed);
//if facing player change movement
}
}
Answer by EHogger · Jul 30, 2013 at 10:26 AM
There are a few different ways to do this.
A simple approach would be to use the player's transform.forward and compare the angle with a vector to the enemy:
float angle = 10
if ( Vector3.Angle(player.transform.forward, transform.position - player.transform.position) < angle) {
}
Its works,but if object is facing from another side, i need to rotate it to another side. How can i check if it was faced from right or left side?
you can check the angle then from left and right to see which one is the smallest.
use the above example but ins$$anonymous$$d of player.transform.forward
use player.transform.right
and -player.transform.right
Answer by fafase · Nov 26, 2015 at 09:30 PM
Another way is to use the dot product. It will return 1 if facing and -1 if looking the opposite. It is based on cosine function so 0 is 90 degrees.
float dot = Vector3.Dot(transform.forward, (other.position - transform.position).normalized);
if(dot > 0.7f) { Debug.Log("Quite facing");}
if 45 degrees (approximate of cos(45)) so it would print when facing within 90 degrees. Make that value closer to 1 to reduce the vision angle.
Answer by FlightOfOne · Nov 27, 2015 at 10:14 AM
I know this is old but maybe this will help someone as it did for me. This post helped me go in the right direction. Below is a method I wrote for a 2D game. This is set for object orientation of my game so may have to play with parameters for your game. (I have Y forward, X right -it's a top down game)
bool IsLookingATObject(Transform obj, Transform targetObj)
{
//direction of the target as a vector
Vector3 direction = targetObj.position - obj.position;
float ang = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
//current angle in degrees
float anglecurrent = obj.eulerAngles.z;
float checkAngle = 0;
//Checking to see what quadrant current angle is at
if (anglecurrent > 0 && anglecurrent <= 90)
{
checkAngle = ang - 90;
}
if (anglecurrent > 90 && anglecurrent <= 360)
{
checkAngle = ang + 270;
}
//If current angle is equal to the angle that I need to be at to look at the object, return true
//It is possible to do "if (checkAngle == anglecurrent)" but some times you don't get an exact match so do something like below to have some error range.
if (anglecurrent<= checkAngle+0.5f && anglecurrent >= checkAngle - 0.5f)
{
return true;
}
else
return false;
}
This won't work when looker's angle is about 90°. Here is fixed code:
bool IsLookingAtObject(Transform looker, Vector3 targetPos, float FOVAngle) {
Vector3 direction = targetPos - looker.position;
float ang = $$anonymous$$athf.Atan2(direction.y, direction.x) * $$anonymous$$athf.Rad2Deg;
float lookerAngle = looker.eulerAngles.z;
float checkAngle = 0f;
if (ang >= 0f )
checkAngle = ang - lookerAngle - 90f;
else if (ang < 0f )
checkAngle = ang - lookerAngle + 270f;
if (checkAngle < -180f )
checkAngle = checkAngle + 360f;
if (checkAngle <= FOVAngle*.5f && checkAngle >= -FOVAngle*.5f)
return true;
else
return false;
}
Sorry to necro, but I went in search of some solution to this same problem. I used this post to help come up with my own solution below. I'm posting it here in case someone else does what I did.. searches for a solution, finding this... I think this below works a bit better. Solution is based partly on qqqbbb's function definition, partly on fafase's, and partly my own work.
bool IsLookingAtObject(Transform looker, Vector3 targetPos, float FOVAngle)
{
// FOVAngle has to be less than 180
float checkAngle = $$anonymous$$athf.$$anonymous$$in(FOVAngle,359.9999f) / 2; // divide by 2 isn't necessary, just a bit easier to understand when looking at the angles.
float dot = Vector3.Dot(looker.forward, (targetPos - looker.position).normalized); // credit to fafase for this
float viewAngle = (1 - dot) * 90; // convert the dot product value into a 180 degree representation (or *180 if you don't divide by 2 earlier)
if (viewAngle <= checkAngle)
return true;
else
return false;
}
I found that all previous answers were missing something (such as looking from a particular angle, or certain FOV ranges), except for fafase's answer.. and it just needed a little cleaning it up to make it a function that can be called quick and easy for anything.
Answer by JannickL · Feb 19, 2018 at 11:40 AM
Hey there, check out that gist: https://gist.github.com/JannickLeismann/bfbb8d0d37c38e78e22e60ae211b597f
public Transform other;
private bool IsFacingObject(){
// Check if the gaze is looking at the front side of the object
Vector3 forward = transform.forward;
Vector3 toOther = (other.transform.position - transform.position).normalized;
if(Vector3.Dot(forward, toOther) < 0.7f){
Debug.Log("Not facing the object");
return false;
}
Debug.Log("Facing the object");
return true;
}
Greets
Answer by mohannadaldakhil · Mar 21, 2020 at 12:08 PM
you can check if two objects facing one another easily by using Dot product between them. the result in the case of facing each other is -1. then check if the angle between your agent and target is bigger than 0 or 7 deg as a threshold.
e.g if (Vector3.Dot(rb.velocity.normalized, targetRb.velocity.normalized) == -1) { if (Vector3.Angle(playerRigidbody.velocity, targetRigidbody.velocity) <= 7) { // the facing each other } }
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Player Controller Rotation Script Help 2 Answers
Make the character face the direction he is moving? 2 Answers
Help with Character Controller 1 Answer