I am looking into optimizing performance. Do you know of a way, that I don’t have to check for collision twice, when checking for collision of many different objects during the same frame? I always think, that I need to check for all objects, that collided, and then do the same inside a “For each” loop, to know, which instance of my colliderObject collided with which instance of my targetObject.
Also…
For anyone trying to optimize collision: I was just testing different collision performances and stumbled across a surprising find, that I wasn’t fully aware of:
Point inside Object seems to be more than 20x as performant than collision tests, Distance checks about a bit more performant and only checking for the single closest projectile at a time about 45% more performant. Here are my Profiler results:
EDIT:
Did a second run and showed similar results, but distance seems to be same as collision (which makes sense, since collision is meant to check for distance first too)
Start with
FIRST
Distance check and distance should be width or height x2 (depending on which is larger) of the bigger object
And under it you check for collision
For example Bullet is 20 width and 5 height
So you would check distance of 40
BUT if enemy is width 30 height 30
Then you would check distance of 60
It could even be 100 in this case
But point is you need to 1st filter object by SOME distance to not check all of them for collision
And then you can check collision against objects you actually care
Think of it like
Reply to any user that had replied to you
Now you are checking all users on this forum did they replied to you
BUT
From users who wrote anything in this topic
Reply to any user that had replied to me
Look how that filtered users you need to iterate trough
For anyone looking for what I was looking for: I did some more tests and found an answer to my question (see point 2 below), as well as some more efficency and precision twerks. Here is what I found.
Point inside object will remain the cheapest option by far. It can miss a collision event, if the ProjectileObject is too fast, or the TargetObject is too small.
Using Collision for all instances and then again for each instance is only needed, if you want a ProjectileObject to be able to hit multiple TargetObjects at once. Instead use Pick nearest object (This is cheaper and will ensure that you only pick one TargetObject).
If you only need “good enough” precision but want good performance and high reliablity only checking Distance first and then Pick nearest objectfor each instance can be sufficient (Given your targetObjects are having the right shape for this)
This isn’t really surprising, testing a single point will always be more efficient than testing a box. “Object in collision” will work when any part of the collision box is overlapping. Whereas, point inside obviously just works on that single point, ignoring any height or width of the object.
This consideration is not unique to Point Inside. Fast projectiles can also skip over things when using the regular Collision condition. They just need to be going a little bit faster since again, you’re checking the entire box, not just the center.
You got it backwards here… you mean that for each is needed if you want multiple projectiles to be counted when hitting Target at the same time.
By the way, you have extra conditions in methods 2-4 that are not needed. It is redundant to repeat conditions unless there’s some specific reason you need to re-filter the objects (such as using Pick All instances):
projectile is in collision with target
repeat for each projectile
(no condition) | do stuff
Thanks for your reply and the addition of possible skips for collision checks. It can be adjusted by legthening the projectiles “tail” (aka lengthening the collision box behind the projectile), if applicable.
Thanks for replying to my initial question. But I think you missed a crucial detail in my phrasing: […]to know, which instance of my colliderObject collided with which instance of my targetObject[…]
In order to know the targetObject of each colliderObject I do need to check for each instance. Otherwise each colliderObject will apply changes to all targetObjects, that collided with a colliderObject during that frame.
On the contrary, it is possible to cut out the collision condition above the for each event. But I wouldn’t want that, since that would be more processing intensive than having it (to easily filter out all objects, that are too distant to my targetObjects).