kernel-legacy icon indicating copy to clipboard operation
kernel-legacy copied to clipboard

Collision triggers

Open nearnshaw opened this issue 5 years ago • 0 comments

We need to have a way to generate four different events:

  1. User touches a wall or floor that has a collider

  2. User stops touching wall or floor that has a collider

  3. User or other entity overlaps with entity that has a trigger

  4. User or other entity stops overlapping with entity that has a trigger

How to implement this needs some debate.
Question 1) Should we do checking for overlaps on the client side or the SDK side?

Answer: we'll be running these calculations on Unity. Partners working on alternative engine must implement something similar on their own.

Question 2) How do we expose these options on the SDK?

Below I propose two alternatives for question 2

Alternative 1:

Add an extra field to shape components, called isTigger. This is similar to how Unity does it.

  • If hasCollisions = true and isTrigger = false, the entity behaves like a collider, as it does now. When the user collides with it, it blocks the user's path, but the entity also emits events (1) and (2). Note: It might be good to be able to turn these events on/off, to not emit them in vain.
  • If the component has hasCollisions = true and isTrigger = true, then the entity behaves like a trigger. When the user or another entity of interest overlaps it, the trigger entity emits events (3) and (4). A shape that works as a trigger is invisible and can be walked through,.
  • hasCollisions = false and isTrigger = true isn't a valid combination.

Pros: Simpler for a developer to implement, one less component to add. Cons: What about shapes like cylinders or spheres? Either we have to have more robust overlap checking, or only certain shape components would support triggers, which would be inconsistent. Also, to add a collision trigger to an entity that has a GLTF shape, I need to add a new entity, set it as a child of the other, give it a box shape, and configure it as a trigger... in this scenario, alternative 1 ends up being more work than alternative 2.

Alternative 2:

Create two new components: BoxColliderTrigger and SphereColliderTrigger (or some other name).

  • If an entity doesn't have any of these components, but has a shape component with hasCollisions = true, the entity behaves like a collider, as it does now. When the user collides with it, it blocks the user's path, but the entity also emits events (1) and (2). Note: It might be good to be able to turn these events on/off, to not emit them in vain.
  • If the entity has one of these components, then the entity behaves like a trigger. When the user or another entity of interest overlaps it, the trigger emits events (3) and (4). If the entity doesn't have a shape component, it will be invisible but still work as a trigger.
  • If an entity has both one of these components and a shape component with hasCollisions = true, this could still be reasonable only if the collider shape has a size that's larger than the shape component.

Pros: these components can be added to any entities, regardless of the shape, for example to GLTF model shapes. The overlap checking doesn't need to handle arbitrary shapes, we can limit it to just spheres and rectangles. Cons: Adding an extra component to entities sometimes requires more lines of code (in some cases it requires less).

Other considerations:

  • The collision components should have properties to set a scale.

Other considerations

For triggers, we need to know which entities overlapping are valid. For example: a bear trap with a collision trigger only triggers the function when a bear overlaps it. Not if it overlaps with a wall.

  1. One alternative is to configure the trigger entity to determine that only entities that have a specific component are relevant for checking overlaps.
  2. We create a new kind of component that activates triggers. Triggers are only activated when an overlap occurs between one of these components and a trigger. We would need to manually add this component to all entities that need to be checked for overlapping with triggers.

How do we know if the user is overlapping with the shape of a trigger?

  1. We just check against the coordinates of the center of the user
  2. If we go with option (2) of the previous question, we give the user a component to activate triggers by default. Or we expect developers to manually create an entity with this component that follows the user's position.

What if the entity's GLTF shape has a _collider mesh (using option (1) from above) we set it to be a collision trigger (overlapping)?

  1. We keep using the collider mesh for collisions (blocking user's path, creating events), but we create a separate simple shape to check for trigger overlaps.
  2. The collider mesh is ignored, and only the trigger shape is used.

Old material about collisions

For more reference, here's an older one-pager about collision triggers.

https://docs.google.com/document/d/1cWw38j95rMuRguZo7QfXbLT5iYSt-Al5fgRbCxjqgeU/edit#heading=h.yrvb8ur2519e

PS, here are some thoughts about that one pager:

  • I don't think it's worth doing a capsule shape, as mentioned there.
  • This paper talks about 3 kinds of collisions. The first one, "overlap" is relevant for both the user and other entities. The second one, "block", should only be valid for the user, as using it with other entities would be closely tied to a physics engine, which we don't have. The third one, "ignore", is just the default behavior when there aren't any collisions of any kind.
  • This paper talks about 3 events. OnCollisionEnter, OnCollisionExit and OnCollisionStay. The third of these is debatable. We might not need it, and (given that it's triggered more times) probably has a bigger effect on scene performance.

nearnshaw avatar Mar 20 '19 13:03 nearnshaw