- Home /
Detect exactly where other objects around player are
I have a player (blue rectangle) which is the center object (can be moved). Other objects will move around the player. What I need is to detect exactly where the other objects lie from the perspective of the player, like the picture below. The circle represent the max distance/radius I need to detect other objects.
I can use InverseTransformPoint to find the x and y of other objects (I dont care about about z), What I need help with, is how can I know in which part (A,B,C..) they are, and how to set them up. Of course this must not be visible in-game and I prefer to handle it from code.
Answer by jakovd · Dec 19, 2014 at 04:25 PM
Good approach would be to keep the references to all those objects in a script. Make a public List of Transforms in your script and drag'n'drop all other objects in the editor to that list. In your code, on the place where you need that information, make the foreach loop that goes through all the elements of that list and calculates the difference of their transform.position and Player.transform.position. Then get the angle of that vector and player's tranform.forward vector with Vector3.Angle(). Use if statements to differentiate which angle fits your A-H parts, like if (angle<15 && angle >-15) {//this is part C}
.
I tried what you suggested, but it is not working as expected
foreach (GameObject car in cars)
{
if(car.transform.name == "$$anonymous$$ercedes_3")
{
Vector3 centerPos = centerObject.transform.position; //player object
Vector3 carPos = car.transform.transform.position; // other object around player
float distance = Vector3.Distance(centerPos,carPos); // distance between the center object and the enemy car
float angle = Vector3.Angle(carPos, car.transform.forward);
print (angle);
}
}
Both objects are cars. But the angle value does not change that much. I am always getting somewhere 160-170. I tried driving behind the other car, in front of it etc, but the angle change is $$anonymous$$imal.
Distance (Line 7) is just a number (length of that distance). What you need is a vector pointing from centerPos to carPos. You get that by subtracting carPos-centerPos. Use that result to get the angle between carPos and that vector (Line 9).
oh, I see, that was dumb! but now I have another problem. isn't the angle supposed to return positive and negative values depending on where the object is? I only get positive
Vector3.Angle always returns the smallest angle between two vectors - it will always be between 0 - 180. If you want to have the "sign" of the angle, then you can use the cross product. Seeing as you're only working in 2D space, it will be something like:
Vector2 fromVector = centerObject.transform.forward;
Vector2 toVector = carPos-CenterPos;
float ang = Vector2.Angle(fromVector, toVector);
Vector3 cross = Vector3.Cross(fromVector, toVector);
if (cross.z > 0) {
ang = 360 - ang;
}
print(ang);
@tanoshimi Tried it, but it returns only values between 180-360
Answer by jeffreymarkbaldridge · Dec 19, 2014 at 08:11 PM
I find breaking these problems down into the most basic form to be easiest.
First put the "Other" objects into the player's space by subtracting the player's world position form the "other's" world position (we'll call this new Vector2, otherVec). This allows you to assume the players location to be the zero vector. Next, all you have to do is use Mathf.Atan(otherVec.x/otherVec.y) to find the degree in radians. Mathf has functionality to convert radians into degrees.
Then with the angle as jakovd stated, you can use if statements to translate into your A, B, C definitions.
http://mymathforum.com/algebra/6201-how-find-angle-given-point-circle.html
Answer by CodeTurtle · Dec 19, 2014 at 05:36 PM
You can calculate the vector between the player and the object, then decide which part the object it is at.
To explain this in a simpler way, imagine there's only four areas around the player(top-right, top-left, bottom-right, bottom-left). After calculated the vector between player and object:
new Vector2 (obj.x-player.x , obj.y-player.y)
We know that if the x and y values are greater than 0, then it is in the top-right section. If x is lower than 0 and y is greater than 0, then it is in the top-left, and so on.
If there are more sections, the same idea can still be applied.
No hard feelings, but I think this solution is actually limited to four sections. Try thinking it through for eight and it soon gets too complicated.