#Represent the object's position relatively to the camera's direction
1 messages · Page 1 of 1 (latest)
In order to calculate the value, you have to get the angle between the lines, starting in p1, camera's position, ending in p2, the point on camera's direction ray, and p3, the object's position
The method may take 2 parameters: camera's and object's (point's) Transform
You first have to create an, optionally, local method to replace the ordinate with the applicate.
The further calculations can be read on the not complicated implementation via code.
private static float GetAngle(Transform cameraTransform, Transform pointTransform)
{
Vector2 p1 = ReplaceOrdinate(cameraTransform.position);
Vector2 p2 = p1 + ReplaceOrdinate(cameraTransform.forward);
Vector2 p3 = ReplaceOrdinate(pointTransform.position);
Vector2 v1 = p2 - p1, v2 = p3 - p1;
float dot = v1.x * v2.x + v1.y * v2.y;
float mag1 = GetMagnitute(v1), mag2 = GetMagnitute(v2);
float angle = Mathf.Acos(dot / (mag1 * mag2)) * Mathf.Rad2Deg;
float cross = v1.x * v2.y - v1.y * v2.x;
return cross > 0 ? 360f - angle : angle;
static Vector2 ReplaceOrdinate(Vector3 value) => new(value.x, value.z);
static float GetMagnitute(Vector2 value) =>
Mathf.Sqrt(Mathf.Pow(value.x, 2) + Mathf.Pow(value.y, 2));
}
Note that the cross product (float cross) is needed to determine whether the object is right or left to the camera, since angle returns 0 - 180 without it.
If you replace the points p2 and p3, cross will return the negative of its current.
Currently, if it's negative, the angle should be kept.
Positive cross means the angle is larger than 180
With this, you are able to represent the angle as a value required.
public static float GetAngleValue(Transform cameraTransform, Transform pointTransform) =>
GetAngle(cameraTransform, pointTransform) / 360f;
The following method returns the value from 0 to 1 clockwise, where, in relation to the camera, the object is:
0-forward.25-left.5-bottom.75-right
It will also never return 1, since 360 deg is 0. So it's from 0 to 1 exclusively. Therefore, no "1 check" is needed
Represent the value the way to wish, and, I hope, this answers your question
This is amazing, thank you so much. I will dive into it now and let you know how it went, hopefully I will not have to ask anything more. Thanks once again.
I have tested it out in an empty scene with the camera and a 3d object, and this works as expected. Make sure replacing y with z is correct for your specific case. Good luck!
I do not quite get "create an, optionally, local method to replace the ordinate with the applicate.". Could you please show me how to get the value in Debug.Log();
(time is really short, sorry for asking)
Not quite sure what you mean. What do you mean by getting the value in Debug.Log?
By "an optionally local method" is meant that the method can be made global, but I've ment it local, since it makes more sense this way, because there is no needed for it to be accessed outside of the method
I just hoped that you could show me more concrete on how to get this up and running, even all the way to a Unity project (maybe you can share a working project if that is less hassle for you. And then I can try to understand the code for real later on). My code skill not that great, especially c#, but I am learning as I go. And I need to install tomorrow. And now I am so close to get it working thanks to you!
What do you mean by "close to get it working"? The two methods I've shared already return the value you were talking about. I've mentioned testing it on a camera and 3D object, so, I suppose, you should be able to use it for your further purposes.
Sorry Im overworked and stressed out, cant think straight. I will try again today.