- Home /
Finding all Objects by Layer within X Radius of Player?
Hello,
I'm building an "auto map" feature that relies on the scenery (Walls, ground, etc) being in the layer "Map Hidden" before the player has advanced through and "Map Seen" once the player walks by. That way, the overhead map camera will only show "Map Seen", and the overhead map will not show locations the player has not actually seen yet.
However, the map scenery do not have colliders, and I'd prefer to keep it that way, so some of the spherical ray casting I've looked at won't work.
Is there another method to cast some sort of ray in all directions and return gameobjects of layer-type-specified?
That's a somewhat limiting solution. What happens when you need to assign one of those hidden objects to another layer? Why don't you just have a monobehaviour that tracks whether an object is hidden? If the gameobject has that component on it then it won't be drawn in the map. Then, once a spherical trigger collider attached to the player comes in contact with that object it will destroy that component.
Other ways to do it: - Set a flag on a general object data script that everything that can be hidden has, setting it when the player is near, and then checking that flag when drawing the map. Slower while drawing, but faster than destroying things. - $$anonymous$$eep a list (or several if you want to more granularly define a grid of lists) of discovered objects and draw only what's in the list. - $$anonymous$$eep a list on undiscovered objects and remove them when discovered. Draw what's not in the list. - Use tags ins$$anonymous$$d of layers.
To answer your question of how to find them, do a SphereCastAll.
Answer by infinitypbr · Jun 20, 2013 at 09:04 PM
This seems to work -- I'm not sure if it's the most efficient way, since it finds all objects, and then narrows down by distance. But it works :)
EDITED: Updated code w/ the distance method described below, added InvokeRepeating so that it does this just once per second.
function Start () {
InvokeRepeating("FindHiddenMap", 0, 1);
}
function Update () {
}
function FindHiddenMap() : GameObject[] {
var goArray = FindObjectsOfType(GameObject);
var goList = new System.Collections.Generic.List.<GameObject>();
for (var i = 0; i < goArray.Length; i++) {
if (goArray[i].layer == 12) {
if ((transform.position - goArray[i].transform.position).sqrMagnitude < distance * distance)
{
goArray[i].layer = LayerMask.NameToLayer("Map Seen");
}
}
}
}
It's not very efficient, no. Ins$$anonymous$$d of finding all gameobjects, just do a spherecast to get those within the radius to start with. I'd recommend only doing the cast every few frames or so, but not every frame if you can help it. Findgameobects and vector3.distance are both slow.
Ins$$anonymous$$d of vector3.distance, use the following formula:
bool inRange = (transform.position - otherTransform.position).sqr$$anonymous$$agnitude < distance * distance;
I was under the impression that SphereCastAll only affects colliders? The docs say "Casts a sphere against all colliders in the scene and returns detailed information on each collider which was hit."
Oh, well yeah, you'd need colliders. :) I was reading on my phone and didn't see that you didn't want them. The method you're using is the best it gets then, but you might consider breaking your world down into a grid so that you're not asking for all of the gameobjects in the scene, but rather within the grid square you're in. That would only serve to speed up your FindHidden$$anonymous$$ap() method, but if your target isn't mobile then it probably doesn't matter.
Your answer
Follow this Question
Related Questions
How do I use layermasks? 9 Answers
Layer mask doesn't work... 1 Answer
Raycast ignore layers except 1 Answer
Why is Raycast ignoring the layer mask? 1 Answer
How would I create a raycast that ignores Character Controller 3 Answers