- Home /
List of objects in line of sight - most optimized way to write it?
So I need to know what objects the character in my game can see at a certain time. Each one of the objects in the world is added to a Univeral Object List on Start()
objManager.pickUpObjectList.Add (transform);
And then each character runs this function
var pickUpObjectsInSightList = new List.<Transform>(); //Contains a list of all the objects the current actor can see.
//Returns a list with all the PickUp objects currently in sight of the actor
function PickUpObjectsInSight(){
var hit : RaycastHit;
var actorHead = boneHead.position;
var viewDistance = 10; //how far the ray is drawn (how far the NPC can see)
//For each object in the list
for(var pickUpObject : Transform in objManager.pickUpObjectList){
var objectCenter = pickUpObject.renderer.bounds.center;
var rayDirection = objectCenter - actorHead;
var ignoreActorMask : LayerMask = -7340037;
//A ray is launched towards each pickUpObject.
if (Physics.Raycast (actorHead, rayDirection, hit, viewDistance, ignoreActorMask)){
//If the ray hits that pickUpObject
if (hit.transform == pickUpObject && !pickUpObjectsInSightList.Contains(pickUpObject)){
// Debug.DrawLine (actorHead, hit.point, Color.yellow);
pickUpObjectsInSightList.Add(pickUpObject);
}
else if (hit.transform != pickUpObject && pickUpObjectsInSightList.Contains(pickUpObject)){
// Debug.DrawLine (actorHead, hit.point, Color.red);
pickUpObjectsInSightList.Remove(pickUpObject);
}
}
}
}
I'm wondering, how expensive is this? Is there a cheaper/clever way to do it? Right now I try to only "look" at the objects in the world when the character is "looking" for something but more and more I find I would use it all the time.
I'm working on something similar and have yet to find a nice solution, but while searching 1 of the answers I found was that you probably shouldn't worry about this unless it's beco$$anonymous$$g a problem.
As in - if it works , you might as well leave it at this for now and come back later if you want to improve the performance or run into problems with it later on.
$$anonymous$$ake of that what you want, but the best way of testing how resource intensive this is would probably be to just fire up the profiler (or whatever it's called in the pro version) and check the stats and how they increase the more you use this... assu$$anonymous$$g that you're using Unity Pro.. there are other, external tools for that too, but unfortunately I can't remember their names.
What's the end goal? Is it necessary to find everything in the line of sight? Can you not just shoot a single ray from the mouse position or to a set of crosshairs for example?
If you must do this, then you may be able to do a Vector3.DistanceSquared check against viewDistance*viewDistance before shooting the ray (no point shooting a ray if it's outside the possible viewing distance) to save a little time.
I would also turn pickUpObjectsInSightList into a HashSet or something similar which has a faster contains method.
List contains method could iterate the whole contents being a O(n) function. But a HastSet contains method is a O(1) function meaning it's much faster.
Other than that, same as ShadoX says, don't worry about it until it becomes a problem.
Another thing to do could be to have a trigger on each character. And then each character keeps their own pickUpObjectList which gets added to when items come into the trigger and removed when they exit. This could vastly reduce the number of objects being iterated for each character.