Left/Right test function

It is easy to get the angle between two vectors using Vector3.Angle, but this only gives an absolute value for the angle. How do you tell if one direction is to the left or to the right of the other?

It seems as though it should be easy, but in fact it’s a little bit subtle. I’ve attached a function (in both JS and C# versions) that illustrates how to go about it. You need to supply a forward direction, the direction that you want to check for left/right of forward and an up direction. The functions return -1 when the target direction is left, +1 when it is right and 0 if the direction is straight ahead or behind.

As is so often the case, the magic ingredient in the function is the cross product.

204420–7536–$leftrighttestjs_122.js (456 Bytes)
204420–7537–$leftrighttest_276.cs (546 Bytes)

18 Likes

many many thanxxx
… how long was i searching for this solution…
Now my Direction Display works !!!
I really miss this in the Doc’s !!!
Great Community !!!
:sweat_smile: kerstin

P.S. Need#s to be on the Wiki !

Thank you very much.
You can get also the final vector, comfortable to transform own collisions.

Vector3 VectorResult;
float DotResult = Vector3.Dot(transform.forward, target.forward);
        if (DotResult > 0)
        {
            VectorResult = transform.forward + target.forward;
        }
        else
        {
            VectorResult = transform.forward - target.forward;
        }
        Debug.DrawRay(transform.position, VectorResult * 100, Color.green);
1 Like

Simple and clean. Good job :wink:

static version?

//returns -1 when to the left, 1 to the right, and 0 for forward/backward
public static function AngleDir(fwd: Vector3, targetDir: Vector3, up: Vector3) : float {
	var perp: Vector3 = Vector3.Cross(fwd, targetDir);
	var dir: float = Vector3.Dot(perp, up);
	
	if (dir > 0.0) {
		return 1.0;
	} else if (dir < 0.0) {
		return -1.0;
	} else {
		return 0.0;
	}
}
1 Like

Thank you so much HigherScriptingAuthority! This is exactly what I was looking for!

Cool script, thanks for this. Here is the C# version:

        //returns -1 when to the left, 1 to the right, and 0 for forward/backward
	public float AngleDir(Vector3 fwd, Vector3 targetDir, Vector3 up)
	{
    	Vector3 perp = Vector3.Cross(fwd, targetDir);
    	float dir = Vector3.Dot(perp, up);

	    if (dir > 0.0f) {
	        return 1.0f;
	    } else if (dir < 0.0f) {
	        return -1.0f;
	    } else {
	        return 0.0f;
	    }
	}
6 Likes

In 2D there is a much simpler way, as explained in this stack overflow question.

public static float AngleDir(Vector2 A, Vector2 B)
{
    return -A.x * B.y + A.y * B.x;
}

This returns a negative number if B is left of A, positive if right of A, or 0 if they are perfectly aligned.

It works by rotating B 90 degrees counter-clockwise (which is simply {-B.y, B.x}) and then taking the dot product to see if the rotated vector is ahead or behind A. (Make some vector combinations with your fingers and wiggle them around until you convince yourself this works! ;))

6 Likes

You saved me a whole night and a gallon of coffee :slight_smile:

Thank you very much HigherScriptingAuthority! Perfect!

great piece of code

If you have a Transform, you can also just take the dot product of its .right vector, and the direction vector.

Also, OP, I think this version of your code would be marginally easier to understand :slight_smile:

float AngleDir(Vector3 fwd, Vector3 targetDir, Vector3 up) {
    Vector3 right = Vector3.Cross(up, fwd);        // right vector
    float dir = Vector3.Dot(right, targetDir);
   
    if (dir > 0f) {
        return 1f;
    } else if (dir < 0f) {
        return -1f;
    } else {
        return 0f;
    }
}
3 Likes

Thanks a lot for sharing this

Thank you so much for sharing this, it’s just perfect for a game I am working on.

Thank you for the share woah i’m now getting to understand how it works XD

if all you need to know is what side an object is on there is another way.

Vector3 localPos = objectFacing.InverseTransformPoint(objectToTest.transform.position);
if (localPos.x < 0.0f) // left side
else if (localPos.x > 0.0f) // right side
else // center

6 Likes

Thanks so much HigherScriptingAuthority! You’ve saved me hours!

@Kev00 That works. Thanks!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SamusDamage : MonoBehaviour
{
public GameObject Player;

public Transform playerTransform;

private float playerPos;
private float collPos;

private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.name == “Reo”)
{
collPos = collision.transform.position.x;
playerPos = Player.transform.position.x;

if (playerPos >= collPos)
{
//you are on the right
}
else
{
//you are on the left
}

}
}

}

this is for 2d

What if the player isn’t facing straight forward?