- Home /
How to find all GameObjects within a specific field of view/box
So I'm making a tower defense game and I'm attempting to make a mode where the user can actually control the aiming of the tower.
I currently have it set up so that the tower finds a gameobject, that gameobject becomes the target and then when it shoots a "bullet" there is a bullet script that just automatically follows the enemy until it hits it.
I'm having trouble thinking of how to do the aiming because it isn't like any other FPS game where the bullet goes straight and just sees if it hits something.
I need to know how to find a target within like a 500 by 500 box for example.
So the logic behind what I want to do is "search for all game objects that are within the camera's view inside a gui box that is 500px by 500px.
So for example:
From there I can just find the nearest.
So this is where I am at in terms of code:
if(target==null){
Collider[] cols=Physics.OverlapSphere(thisT.position, range, maskTarget);
if(cols.Length>0){
Unit currentTarget=null;
Unit targetTemp=null;
//we are in first person mode, and we are on manual, so the user is aiming, is he aiming at a target?
if(firstPersonMode == _FirstPersonMode.Manual){
float dist=Mathf.Infinity;
Collider currentCollider=cols[0];
foreach(Collider col in cols){
float currentDist=Vector3.Distance(thisT.position, col.transform.position);
if(currentDist<dist){
if(col.bounds.Contains(HOW TO FIND THAT BOX I DREW)){
currentCollider=col;
dist=currentDist;
}
}
}
//actually sets the current target
currentTarget=currentCollider.gameObject.GetComponent<Unit>();
if(currentTarget!=null && currentTarget.HPAttribute.HP>0) target=currentTarget;
}
}
Any information that might help me is appreciated.
Thanks for reading.
It's unclear what you are doing exactly, please clarify:
When a user takes control of the tower, they will be ai$$anonymous$$g by themselves won't they? If they aren't how do you plan to do this. Will the bullets still be 'ho$$anonymous$$g' bullets/missles?
Also, do you want all gameobjects, or just all enemies that are in view? This part you should not worry about the view and just use the boxcollider with trigger set to detect. This in effect is an AABB and just records when something enters it. If you insist for whatever reason, you could cast a ray out in your current view x-meters and establish a new box collider with certain dimensions (you can transfer camera viewport to worldpoint with that function viewportTo.. something, can't remember atm).
Yes, the bullets will still be 'ho$$anonymous$$g', it just won't be able to shoot unless the enemy is within that box.
The user will be ai$$anonymous$$g the tower, just as you would in a FPS game, just only rotation not actually moving.
Beyond that, you are correct I don't want ALL gameobjects, I just want the enemy. However I already know how to do that if I could just figure out the box thing.
I'm currently making a work around that I will post as an answer soon, doing some testing and what not. Unless of course you know how to detect all gameobjects that are in the view of that box.
The idea is, I know that the GUI is a vector2, it only has an x and y. It's "flat" if you will. But if I could make that gui box have a x y and z, it would "infinitely" stretch out in the z axis, therefore anything within that box would be found because it would literally be colliding with it. I'm currently doing this by adding a box collider to my camera (still in testing)
I'm not sure what you are trying to do here. If you are trying to detect what objects can be seen through a rectangle, then you have to take perspective into account. That is, more of the scene is visible at a distance than closer in, so a cube doesn't work. One solution is to project the position of your object onto the screen either as a screen coordinate or as a viewport coordinate. You can do this using Camera.WorldToScreenPoint() and Camera.WorldToViewportPoint(). Then you can check the position against a rect. It is easier to check if the central pivot is seen in the rectangle. It is a more difficult problem to check if any portion of an object is visible.
Answer by trs9556 · Jun 17, 2013 at 04:33 AM
NOTE: This is the answer for me, this is what I did and it achives exactly what I wanted. I do want to point out it might not be the most effiecent, I say this because I haven't tested anything else. If I didn't already do this while waitting for an answer I would of used SinisterRainbow's answer, so thanks. robertbu was also on to something.
THANKS ALL
THAT'S what I was looking for, I knew I could use rays but I didn't know how. I've never used ray, just know about them.
I have however figured out something that works, already tested and what not.
So I added a box collider to my camera and I just activate it when I need to use it. Basically it's acting as my "gui box" and if there is a enemy within it's bound I am aiming at it.
So:
So as you can see, because my camera is a child of my tower it will follow it. And if there is an enemy within that box (the long one) it will mean "the user is aiming at it).
My code was easy to do as well:
//we are in first person mode, and we are on manual, so the user is aiming, is he aiming at a target?
if(firstPersonMode == _FirstPersonMode.Manual){
float dist=Mathf.Infinity;
Collider currentCollider=cols[0];
foreach(Collider col in cols){
float currentDist=Vector3.Distance(thisT.position, col.transform.position);
if(currentDist<dist){
if(col.bounds.Intersects(Camera.main.collider.bounds)){
currentCollider=col;
dist=currentDist;
//actually sets the current target
currentTarget=currentCollider.gameObject.GetComponent<Unit>();
if(currentTarget!=null && currentTarget.HPAttribute.HP>0) target=currentTarget;
}
}
}
From a first person's view it looks like:
Answer by SinisterRainbow · Jun 17, 2013 at 04:23 AM
OK, then the answer(s) are simple. There's a function where you can translate the camera viewport (forget the gui) into world coordinates. http://docs.unity3d.com/Documentation/ScriptReference/Camera.ViewportPointToRay.html
Just cast out a ray and instantiate an empty gameobect with a collider/trigger that will record when enemies enter.
HOWever, why do it this way? Why not set up a boxcollider w/ trigger around the tower in the first place and not worry about what view you are in.
I see, you needed it to aim as well. If that's the case and ure doing it like this, why do you need to detect multiple enemies? Just send out a single raycast every frame or two and whatever it hits is what you're ai$$anonymous$$g at. Edit: Because if you're detecting all enemies this way, then it may look funny to shoot an enemy that is behind another enemy first. The bullet may pass through the closer enemy. With a raycast it tells you which one is in front. I dunno, maybe that's not important in your game.
float currentDist=Vector3.Distance(thisT.position, col.transform.position);
if(currentDist<dist){
This snip it finds the closest one. I don't want to just aim at any old target, just the closest. The reason for this is because it's a tower defense game, and the range of my towers aren't amazingly huge. So by getting the closest one it will allow for the best user experience because they will be able to shoot the longest. It avoids just shooting once. If you get the closest it allows for multiple shots. $$anonymous$$akes the user feel like they are doing good basically. (and when it comes to a game its all about the user)
So I get every enemy within the tower's range, I then get the closest one that is within the ai$$anonymous$$g.
Your answer
Follow this Question
Related Questions
Primitive Collider slower then mesh collider 0 Answers
Internal collisions 1 Answer
Is Mesh Collider Optimal for GUI? 2 Answers
Collider going through walls with box collider.. 1 Answer
OnCollisionEnter: collision.gameObject has weird behaviour 0 Answers