3
votes

I am trying to determine the angle where the camera forward vector intersect with an object vector.

Sorry, not straight forward to explain with my knowledge, please find attached a diagram: The camera may not be looking directly at the object (OBJ) and I'd like to know the angle ( ? in the diagram) where the camera's forward vector (V1 in red) intersects with the vector of the object (V2 in red) (if it does), e.g. point A, or B, or C, etc depending on the x-rotation of the camera.

diagram

I tried calculating a normalized vector for the red lines, v1 and v2. Then calculate the angle between two vectors https://onlinemschool.com/math/library/vector/angl/ But the results don't match the expected values when testing.

//v1
Vector3 hypoth = Camera.main.transform.forward.normalized;
//v2
Vector3 adjacent = (new Vector3(obj.transform.position.x, obj.transform.position.y, Camera.main.transform.position.z) 
                        -obj.transform.position).normalized;

float dotProd = Vector3.Dot(adjacent, hypoth);
float cosOfAngle = dotProd / (Vector3.Magnitude(adjacent) * Vector3.Magnitude(hypoth));
double radAngle = Math.Acos(cosOfAngle);
float angle = (float)((180 / Math.PI) * radAngle);
2
Doesn't adjacent point away from obj unless you do (obj.transform.position - new Vector3(obj.transform.position.x, obj.transform.position.y, Camera.main.transform.position.z)).normalized; ? - Ruzihm
It would probably help if you explained why you need the angle - does it need to be signed? If so, what does a negative angle indicate? Depending on what your intent is for the angle, you may not even need to calculate the angle at all. - Ruzihm
as you have it painted with a known 90° angle couldn't you simply do 180f - 90f - Vector3.Angle(camera.forward, (obj.position - camera.position).normalized) - derHugo
Hi @ruzihm sorry for the delay, was out travelling and couldn't test it. Your proposed solution worked but I had different heights for objects so my diagram was not accurate leading to inconsistencies. In the end I raycasted for objects in front of the camera as a good enough solution - the objects are big enough. Thanks a bunch for your help :) - Sergio Solorzano

2 Answers

3
votes

Finding the angle between v1 and v2 gives you this angle, which doesn't match what you mark in your diagram:

what your code is calculating

Instead, solve for the angle between v1 and the plane normal to v2:

diagram explaining why this works

We can do this in unity by projecting v1 to the plane normal to v2 using Vector3.ProjectOnPlane, and then finding the angle between that projection and v1 using Vector3.Angle:

Vector3 projection = Vector3.ProjectOnPlane(hypoth, adjacent); 
float angle = Vector3.Angle(projection, hypoth);
0
votes

I've a similar situation where I wanted to set the collidars of the terrain units on the same height of the player Jet and at the same time it must be on the line of sight of the camera, otherwise when u shoot the terrain units , the bullets will appear like moving through enemy units on the ground , this only works when you work with prospective camera, on orthongal , u may dont need to do this at all, its just set the object on the same height as the camera and everything will be aligned .

Here is my code

 void SetColliderLocation()
{
    // Object on the ground
    A = TerrainUnit.transform.position;
    // Camera location
    B = cam.transform.position;
    // Enemy jet height 
    height = mainPlayerTransform.position.y;
    // Unit Vector normalized between A and B
    AB_Normalized = (A - B).normalized;
    // The unit vector required to move the collider to maintain its hieght and line of sight with the camera
    unitVector = (height - A.y) / AB_Normalized.y;
    // Setting the location of the collidar .
    collidarGameObject.transform.position = (AB_Normalized * unitVector) + A;
}

I hope its some how similar of what you are looking for.

Edit:

If you applied this script and instead of collider you put a box , you will see the box location will be always between the camera on the sky and object on the ground however the camera or the object on the ground is moving.