Problem dealing with colliders in a complex project [SOLVED]
Hi everybody!
This is my first post here.
I don't like to ask for help, I prefer to search by myself, but I've a pretty specific problem there, and I didn't find any fairly accurate answer... So here I am !
Just to let you know, my project is too big to give some code here, so if you really want it, I'll do a short version, but I'll not if it's not necessary (and I don't think it is).
So here is my project
I have some creatures gameobjects, which have rigidbodies and their own colliders, to fall down with gravity, to be stopped by the ground, and to be hit by some raycast from the mouse click.
I have some empty object to simulate their visions (to detect other creatures and food). These objects have sphere colliders (for now) to simulate a simple vision around the creatures. Their positions are replaced by the corresponding creatures' positions at every update.
I have some food gameobjects , placed on the map, my creatures will detect to eat.
I have a lot of other things, but nothing important for this problem, I think.
And now here is my problem
At the beginning of the game, some creatures spawn with some foods, and then some food object are inside the vision colliders. If I check the isTrigger vision colliders, they'll not detect the food that is inside it... But if I uncheck it, the creatures will be thrown away because of their rigidbodies... And if I remove the creatures rigidbodies, they'll obviously pass through the floor...
So I would like creatures to have a normal life with their rigidbodies and normal colliders, I would like visions to detect creatures with a second collider, and I would like raycast to hit only creatures and not visions.
Tried solutions
At the begninning, I had the visions colliders on the creatures, but Unity just merge two collider on the same object, so the raycast could not hit only the creature, ignoring the vision... And I can't either put the visions objects as children of the creatures because Unity merge colliders too in this case...
I tried to deal with it with the layers, but if visions don't interract with creatures, the creatures will not detect other ones. So the layers only fixed my raycast problem.
I don't want to do the vision manually by checking distances (to do like a sphere collider), because I'm not sure it's optimized (I have to deal with a lot of creatures, and the script is already a little heavy), and I'll maybe change the vision collider type to make some conical vision or something like that in the future.
So I really don't know what to do. Does anybody have any idea ? About how to do a working vision without additional colliders ? Or about how to deal with those freaking colliders ?
Thanks in advance !
(PS : Ho, and I'm not english, so sorry for my bad english.)
I'm still thinking, I'm sure others are too, but I wanted to comment as a preface to helping you with a few points.
1) Your English is good. I've discovered that Google's translate, lately, has become quite good with certain languages (not so much with others), but if you're unsure as you write, it may be a good assistant reference, maybe even to take your English as input and translate back to your language to see if it understood.
2) While I'm considering the implications, it strikes me to say an old axiom, premature optimization is the root of evil. It's not always correct, as we often writing knowing what is efficient, but we're constantly surprised about what actually is heavy and what turns out to be fast. Test, and don't make assumptions - get things working first, then use that to analyze the algorithm (both with performance testing and algoritmic analysis) to consider optimization later (for the most part).
3) That said, I fully understand your performance concerns, but then I don't know what you might mean by lots of creatures...how many collisions are we considering?
4) You have a situation where filtering is required. Layer's aren't sufficient. Colliders are a typical and good solution, but filtering is up to the response methods which are fed a long list of collisions we need to ignore. Sometimes we really have to recognize that the physics system (which performs the collisions) may not be our best solution. A hint to give you thinking relative to your point about checking distance, a typical use case is to resort to distance squared. This is because to get a distance between vectors requires a square root (the heaviest part of that calculation), but we can sense a range by using distance squared (which is the distance calculation just before - and therefore skipping - the square root). Our only difference is that if we have a range in $$anonymous$$d, we square that range before we use it to filter by distance squared - and it's fast. I'm therefore hinting that you may want to avoid using collisions and scan a list of just the food you're looking for, ranged by distance squared. That can even be faster. Assume there's a AABB (aligned box) around your creature. Any food object with x, y and z coordinates outside that box can be rejected with only comparisons (not even the first part of a distance calculation) - it's an early rejection approach that makes what is already fast even faster. Finally, you're thinking in terms of the creature looking outward, and that is the game's perspective, but if the volume of food items is much larger than the volume of creatures, you may be better off looping through the food items and imaging they could see the creatures, as a means of figuring out what's in range - that's may be a smaller problem to compute.
Thank you for your answer ! And thanks for the first point, I work on my english everyday.
For the second point, I get what you are saying, but to continue with the next point, the game has to deal with like 300 creatures, and a little bit less foods. So the number of collision is really high (even if I don't really know what "high" digitally means to unity...). But I'll give a try to manually made vision !
However, I do not totally agree with the 4th point... The squared distance could be a good idea if the vision would be a simple distance (sphere collider) forever... But, like I said, the thing is it will be something else, like a custom mesh collider, or even one (or more) raycast(s). I don't know yet. So I don't think it will fit to this project if I want to preserve the open/close principle.
Or else, I could make it by creating a box around the vision ins$$anonymous$$d of around the creature, but it'll have to find the center of the vision, or the maximum and $$anonymous$$imum x/y/z, or something like that... And I don't even know if it will always be possible...
But let's go back to what you said before : I'll do something working first, and then I'll see how to improve things ! I just hope it will not be to awful to improve one little thing by modifying to much code.
Anyway, thanks again for your answer ! You opened my point of view on this problem. I always wait for a perfect magical answer, but apparently, there are not that much anymore where I have reach in unity...
"I always wait for a perfect magical answer, but apparently, there are not that much anymore where I have reach in unity."
That's funny. After 30+ years in development work, I can attest those don't exist, and where it has ever seemed so, there's usually a cost somewhere that isn't expected.
"But, like I said, the thing is it will be something else, like a custom mesh collider, or even one (or more) raycast(s). I don't know yet."
A field of vision is simulated in most 3D systems as a view frustum (chopped off pyramid with the large end facing away). There's a step in the GPU pipeline where all objects are culled based on whether any portion of them are within the view frustum. The frustum shape is a reflection of the rectangular display, and eye would more fit inside a conical section. When a frustum is used, object locations are tested against plane equations to see what side they're on, and when combined from all frustum sides, one can see if the object is within or outside of the frustum. A cone has a similar counterpart (entirely different math). Raycasts are more like "try to hit something with a beam" - a random kind of act. You know the objects of interest already, so you're working from the reverse perspective. When you compare the cost of a frustum, cone or other shapes, you'll end up realizing that performance objectives favor merely deter$$anonymous$$ing the distance (squared applicable) and angle to and object ($$anonymous$$athf.Atan2), and deter$$anonymous$$e if that lies within the range of interest. This is like a polar coordinate of the objective.
I've worked on 3D rendering engines and physics engines in my career, so I have various concepts firmly in $$anonymous$$d from various use cases that come from how both solve these problems. If you take a tour of the entire 3D rendering pipeline, and/or the collision system of a physics engine, you'd have dozens of ideas like those I've mentioned thus far. A point most who learned all of this from making Unity games will miss, when they suggest colliders and triggers in the context of your objective, is the fact that you only need to consider locations, while the colliders ultimately consider the entire geometry of the objects involved. That includes the OverlapSphere. Under the hood, it performs fast rejection (a broad phase), but any candidate object that isn't entirely outside or inside is tested for what portion of intersection may exist, accounting for the mesh of a detailed model. This is much heavier than merely searching for objects by a central point (location).
This brings me to a question we haven't communicated. You're simulating vision - are you concerned about obstruction of view? (Hint, there's a 'thing' for that, just not necessarily a built in Unity thing).
Good day.
I dont get whats the problem of select "trigger" option. You can always combine OnTriggerStay() with Vector3.Distance() to be sure what are you detecting.
Hi! Thanks for your answer !
The thing with "trigger" option is that neither isTriggerEnter nor isTriggerStay detect other colliders that are already inside the collider. And the distance is an other way to do a sphere collider, but it will not always be a sphere collider, so I can't only count on it...
Your answer
Follow this Question
Related Questions
OnTriggerEnter no longer works 1 Answer
How to trigger a BoxCollider with a RigidBody? 0 Answers
ANIMATION TRIGGER DOESN'T PLAY 1 Answer