How to tell when the character is facing a certain direction

Is their a really easy way to tell if my character is facing forward or backwards.

The camera is fixed behind him and doesn’t rotate, I need to find a way to figure this out so i can execute a turn animation in Mecam( its magic )
This is what I have so far, and it only works so so, the idea is when you need to change direction you do a 180 turn

public int direction ; 
	void Update () 
	{
		if(Input.GetAxis("Vertical") >  0){
			if(direction != 0)
			{
			TurnN();
				direction = 0 ; 
			}
				// 0 is forward, 1 is backwards
		
		}
		
		else
		{
			if(direction!=1){
				TurnN();
				direction = 1 ; 
			
			}
			
		
		}
}

I like to nest my model so then I do all translation and rotation etc on the parent , then all reverse movements are simply multiplication of the transforms forward vector by 1 or -1. When this happens I rotate the inner nested model by 180 for the visual of having turned around.

Here is another snippet of code for checking if two transforms are facing each other or not :

float angleThresholdToCheck = 90;
Vector3 targetDir = otherCharacter.transform.position - thisCharacter.transform.position;
Vector3 forward = thisCharacter.transform.forward  * inputVectorNonZero.x ;
float angle = Vector3.Angle(targetDir, forward);				
if(angle >= angleThresholdToCheck){
	//do whatever
}else{
	//do whatever
};

take note that I multiply the forward vector by the current direction which I store in the variable “inputVectorNonZero” - this is only based on my previous mentioned system where I dont do turn around rotations on the transform but rather use a polarity

This would be in an update right ?

This bit
“inputVectorNonZero.x”
is returning as not defined in the current context, when I swapped it out for Input.GetAxis(“Vertical”)
I get unpredictable behavior .

You can leave than bit out , I tried to outline this in my description when I posted the code - I use this variable ( which I store a direction in ) only because I dont actually do turn around rotations on my transform , I use the input as a polarity to invert the forward vector.

anyway here is the code revised. Everything else is the same except the multiplication of this variable :

float angleThresholdToCheck = 90;

Vector3 targetDir = otherCharacter.transform.position - thisCharacter.transform.position;

Vector3 forward = thisCharacter.transform.forward ;

float angle = Vector3.Angle(targetDir, forward);                

if(angle >= angleThresholdToCheck){

    //do whatever

}else{

    //do whatever

};

Just after posting again now I thought I should rather be more concise to you first post . The Code above works for checking if two transforms are within a certain angle of each other and is useful , but in regards to your actual internal processing of your characters movement this would be overkill.

If you are using input to change directions then instead of using 0 and 1 to mean forward and backward , rather use the exact values returned from your call to GetAxis which are in the range of -1 to 1 . here is an example :

public Vector2 inputVector = Vector2.zero;
public Vector2 inputVectorNonZero = Vector2.zero;

public void Update() {
	inputVector.x = Input.GetAxisRaw("Horizontal");
	inputVector.y = Input.GetAxisRaw("Vertical");
	
	if(inputVector.x != 0){
		inputVectorNonZero.x = inputVector.x;
	};
	
	if(inputVector.y != 0){
		inputVectorNonZero.y = inputVector.y;
		
	};
}

I use similar code to this , its in an external input class , and my character then simply interprets the two variables stored from GetAxis.

You may ponder why two variables so here is why :

The one variable “inputVector” stores the values from GetAxis ( this is used to affect translation calculations , eg : any non zero value will mean movement and the value of zero, when no key is pressed, means no movement)

The other variable “inputVectorNonZero” is exactly that … it stores the values from GetAxis but not if they are equal to zero. ( this is used to affect direction calculations )

In my class that handles moving the character I do something similar to this :

if(inputVectorNonZero.x <0){
	userRotation  = -180;
}else{
	userRotation = 0;
};

Again I dont think I was concise to your needs LOL … anyway I hope something of all this blabbering of mine was helpful :wink:

All help is appreciated, my earlier solution solution worked somewhat( like half the time ) . I will try your code a bit latter .

The thing about my game is its only when you need to turn around should

Input.GetAxis(“Vertical”)< 0
turn you around . Its like I need to know when the user needs to turn around .

See if your already facing the camera and you hit the joystick down it makes no sense to turn around

I couldn’t read the whole thread but I didn’t see somebody offering Vector3.Dot as solution. Will it help ? You can check it like that:

var aligned : boolean = false;
if(Mathf.Abs(Vector3.Dot(player.forward, Vector3.forward)) == 1) aligned = true;

This will return true if the player’s forward is completely aligned to world’s Z no matter if facing forward or backward.

Dark Protocol, that code is wrong, it will also return true if the objects are facing completely opposite directions because you’re looking at the absolute value of the dot product.

The dot product of two vectors will give you a float value representing the angle between them, note I said representing, not exactly an angle. If will return a positive number if it’s within 90 degrees, exactly zero if the vectors are exactly perpendicular (at a right angle) in either direction, or a negative number if it’s greater than 90 degrees. They can’t be more than 180 degrees different because at that point they’re pointing in completely opposite directions.

Another really handy tidbit is that if both vectors are normalised, the return value will be between 1f and -1f. (if they are not normalised there’s no sane way to tell what range the values will be in, it could be from +/- 0.4 or +/- 3000) So if you want to test if something is facing a particular direction (or close enough to) you can do the following:

	public bool CompareDirections(Vector3 headingA, Vector3 headingB, float bias = 0.01f) {
		if(Vector3.Dot(headingA.normalized, headingB.normalized) > 1f - bias) {
			return true;
		}
		return false;
	}

Of course the .normalized can be a bit slow if you’re doing it several times per frame on a lot of different objects, but often you don’t need to as things like transform.forward are already normalised vectors.

It’s not wrong. I think keithsoulasa wants exactly that. But yes, if you want to check only one direction you would not use Mathf.Abs :slight_smile:

Yep, and I’m assuming this is the same code in C#

public bool  aligned = false;

if(Mathf.Abs(Vector3.Dot(player.forward, Vector3.forward)) == 1) aligned = true;