Hey Norbo, I'm building a graphically 2d action rpg using BEPU. It's working out great -- making things like jumping and projectiles really fun to set up. I'm getting to the point where I have to decide on how I'm dealing with collision rules for my simulation, and I thought I'd ask your advice.
I'm using a modified version of the SimpleCharacterController for heroes and some enemies, while other enemies just get a simple rotation-locked sphere or box. I've also got lots of trigger areas, which can be either cylinders or boxes, which are meant to collide with nothing but the thing that triggers them. I'm using attack hitboxes in a similar way, and I've also got item drops, which collide with walls and the floor, but nothing else (found it annoying to have them collide with heroes/enemies).
Up until now I've mostly relied on collision groups, and not used the personal or specific collision rules much. However, when I started using the SimpleCharacterController, I ran into a problem -- the raycast on it, not being part of a collision group, collides with everything... even trigger areas, attack hitboxes, and other things never meant to do anything but raise events.
I understand I can use the overload of the broadphaseentry.raycast to provide a filter. However, the problem got me thinking more about how I've been using the collision rules, and only relying on the collision groups, which doesn't seem like the best use of the engine.
I came up with a new solution: create a few specific collision rule dictionaries named things like "OnlyHero" and "OnlyEnemy", and just have each creature, as it's being created, add itself to this universal specifc dictionary. Then, trigger areas can simply reference whatever specific dictionary is appropriate for them, and then have their personal rule set to CollisionRule.NoBroadPhase.
My question is a pretty general one: are these equally valid approaches? Is there an obvious better way to approach the complexity of all these interlocking collision rules?
Also, lets say I create a specific dictionary called "OnlyWalls". Every wall, when the level is loaded, is going to add itself to this group. This is going to lead to a really massive dictionary. If I have a bunch of objects all using this OnlyWalls specific dictionary, is that going to take a lot more effort to look up each wall piece than just a simple collision group? Should I avoid making specific dictionaries with thousands of entries?
Another idea is to change the CollisionRuleCalculator to look at collision groups before personal rules. That way, things could still obey collision group rules, but also have a default personal rule of NoBroadPhase, if no collision group relationship exists (as in the case of the character controller's raycast.)
Sorry about the length. Thanks for reading, Norbo.
Alex
*edit* I guess another approach would be to set up a collision rule instance for each type of game object (hero, enemy, trigger area, etc..), define the relationships between them, and then set every individual game object, on initialization, to reference those collision rules. That way there wouldn't be as many entries in the specific dictionary, but I haven't quite worked out how things would work with all enemies sharing the same collision rules... hmm
Best use of collision rules?
Re: Best use of collision rules?
The main consideration is to minimize the amount of effort you, as the developer, must expend to set up relationships. So, if it looks like such dictionaries would make things easier, I'd say that would be fine. Performance is a secondary concernI came up with a new solution: create a few specific collision rule dictionaries named things like "OnlyHero" and "OnlyEnemy", and just have each creature, as it's being created, add itself to this universal specifc dictionary. Then, trigger areas can simply reference whatever specific dictionary is appropriate for them, and then have their personal rule set to CollisionRule.NoBroadPhase.
My question is a pretty general one: are these equally valid approaches? Is there an obvious better way to approach the complexity of all these interlocking collision rules?

Performance wise, looking up values in a large dictionary hundreds of times every frame will be more expensive than small dictionaries, personal rules, and collision groups. It's hard to say exactly how much slower it would be without testing it, but I'd guess that the extra cost should not be prohibitive.If I have a bunch of objects all using this OnlyWalls specific dictionary, is that going to take a lot more effort to look up each wall piece than just a simple collision group? Should I avoid making specific dictionaries with thousands of entries?
With my limited exposure to the details, I'd probably choose this over the previous option due to the simplicity of implementation. It's one central change and most of the code is structurally identical.Another idea is to change the CollisionRuleCalculator to look at collision groups before personal rules. That way, things could still obey collision group rules, but also have a default personal rule of NoBroadPhase, if no collision group relationship exists (as in the case of the character controller's raycast.)
By the way, if all you need is to default to NoBroadPhase for undefined pairs, you could set the CollisionRules.DefaultCollisionRule to CollisionRule.NoBroadPhase.
That's doable too, though it sounds suspiciously similar to how CollisionGroups work*edit* I guess another approach would be to set up a collision rule instance for each type of game object (hero, enemy, trigger area, etc..), define the relationships between them, and then set every individual game object, on initialization, to reference those collision rules. That way there wouldn't be as many entries in the specific dictionary, but I haven't quite worked out how things would work with all enemies sharing the same collision rules... hmm

Re: Best use of collision rules?
You know, I even thought of changing the default collision rule (I swear!) but somehow it didn't occur to me how elegant of a solution that would be until you said it. Been adding some collision rules (for normal collisions) and it works great! This way I get to save specific rules for things like objects with multiple parts that shouldn't collide with themselves -- stuff that's really easy to set up.
Thanks Norbo!
Alex
Thanks Norbo!
Alex
Re: Best use of collision rules?
I've just noticed that changing the default collision rule won't work for solving the raycasting problem with the SimpleCharacterController, though -- the raycasting of the simple character controller still seems to detect things even after I set CollisionRules.DefaultCollisionRule = CollisionRule.NoBroadPhase. (I'm just basing this on the fact that my character still steps on top of detection areas). This is probably intended though, since as far as I know raycasts don't have a collision group. It seems like giving objects personal rules like NoSolver or NoBroadPhase is the only way to get them to not collide with a raycast?
There are some assumptions on my part here about what's really happening under the hood. The behavior that I'm trying to avoid is my character controllers landing on top of trigger areas (the trigger areas' collision groups are set to NoSolver or NoBroadPhase against every other collision group). It's also strange that a character walking into one of these trigger areas slowly rises until they get to the top of the area -- I'm assuming this is the simpleCharacterController's up-stepping kicking in.
There are some assumptions on my part here about what's really happening under the hood. The behavior that I'm trying to avoid is my character controllers landing on top of trigger areas (the trigger areas' collision groups are set to NoSolver or NoBroadPhase against every other collision group). It's also strange that a character walking into one of these trigger areas slowly rises until they get to the top of the area -- I'm assuming this is the simpleCharacterController's up-stepping kicking in.
Re: Best use of collision rules?
I ended up just going into the SimpleCharacterController and adding this line to the FindSupport function:
if (CollisionRules.GetCollisionRule(Body, candidate) != CollisionRule.Normal)
continue;
That way, anything that wouldn't collide normally with the character's body doesn't get tested against the support raycast. Seems to work great.
As always, thanks for your help, Norbo!
Alex
if (CollisionRules.GetCollisionRule(Body, candidate) != CollisionRule.Normal)
continue;
That way, anything that wouldn't collide normally with the character's body doesn't get tested against the support raycast. Seems to work great.
As always, thanks for your help, Norbo!
Alex
Re: Best use of collision rules?
Yup.This is probably intended though, since as far as I know raycasts don't have a collision group.
Yup again.It's also strange that a character walking into one of these trigger areas slowly rises until they get to the top of the area -- I'm assuming this is the simpleCharacterController's up-stepping kicking in.
That is pretty much what I would have recommended.I ended up just going into the SimpleCharacterController and adding this line to the FindSupport function:
if (CollisionRules.GetCollisionRule(Body, candidate) != CollisionRule.Normal)
continue;
That way, anything that wouldn't collide normally with the character's body doesn't get tested against the support raycast. Seems to work great.
