Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Strategy for collision handling

Discussion in 'General Discussion' started by bitinn, Aug 2, 2019.

  1. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    One thing I always wonder when people use DrawMeshInstanced / Indirect, is how do they setup the collision detection when there isn't a GameObject.

    AFAIK, in games with very large and dynamic map, like Cities Skylines, collisions are simply ignored. But what if you are an action game, how do you stop the player from getting into geometry? Raycast against movement direction? Use map data to prevent players from moving into invalid position?

    In short: I am going the DrawMeshInstanced rendering route, and realized I can't use the built-in collision system without gameobject, what could I do?

    (There is also the question of NPC navigation, but given I have the data for rendering, I can build a grid map or flow field for that, so less of an issue.)
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    I am unclear what you are asking for.
    Use simply colliders?
     
  3. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    I don't have GameObjects associated with rendered geometries (eg. no GameObject / MeshRenderer in scene), so I can't use Collider / Rigidbody component neither.
     
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    You can use spatial mapping, or similar techniques as A* (A star).

    What kind of game do you make, which doesn't have game objects?
     
  5. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    Your could have game objects with no renderer only collider and use that for the physics simulation. Than use the gameobject transform to draw the mesh on the correct place
     
    Antypodish likes this.
  6. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    My problem isn't really genre specific, but rather I am trying to render geometries with DrawMeshInstanced and do manual culling myself. Hence I have this "no gameobject" problem.

    (I didn't aim for zero gameobject, just avoiding gameobjects in general for performance sake, as the level is dynamic and contains modular pieces; otherwise I would have combine mesh and use mesh collider...)
     
  7. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    I could do that, but given the number of modular pieces, I would either need:

    1. many gameobject, primitive collider, no mesh needed.

    2. fewer gameobject, some logical grouping and mesh collider, require combined mesh to create fitting collider.

    3. no gameobject, render directly, but come up with some smart custom collision detections and triggers.

    I can reasonably pick 2 or 3; I was heavily invested in option 3 and came up with a good render strategy but now have to come up with a collision detection solution...

    ----

    Let's imagine a simple scenario:

    - Say our game is like a lot (aka a house) in The Sims.
    - Say we can control a character that walks inside this house
    - Say we can build/demolish rooms as we see fit.

    Now, given the number of modular pieces here: Option 3 seems like a good strategy, until I realize it's a bit of a problem when you give direct control of character to player.

    If the control is like The Sims, then I can simply check for valid position and move using a navigation system, backed by the map data.

    But since players have direct control, collision detection is needed, so Option 2 seems like a better strategy, but performance of Mesh Collider does concerns me even if we combine pieces per room...
     
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    You are probably better to use PhysX native features, as these are highly optimized, for collisions.
    And are multi threaded.

    Other than that, it seams you are starting worry far too early. It appears you talking mainly about static colliders.
    Did you run any stress tests and profiler, to confirm any of your concerns? Please do if you haven't and post here results. Then we can start worry, how to improve, if needed.

    Edit:
    For sake of discussion, I did while ago stress test of 5k falling and colliding stack blocks at the same time with each other. The lag happens, when all hit the ground at the same time. That means at least 5k pairs of collisions. Probably more than 10k at given frame. That heck a lot for most games. No much issue with 1000. And if you got only few collision per frame, that nothing to worry. How many objects in on the scene is least relevant.
     
    bitinn likes this.
  9. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    I for fun tested to create a composite primitive collision with thousands of primitive colliders. Zero impact on perfomance on desktop
     
    bitinn and Antypodish like this.
  10. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
  11. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    Yeah. Composites are well optimized with PhysX.
    Making own collision system, will probably lead to bottle neck, if not deep into the subject.
    Jobs and DOTS will be more suitable for that purpose.
     
    bitinn likes this.
  12. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    True, kinda why I want to run it through people here to see if it's something people do.

    I know there are solutions with ECS here but because I am on 2018 LTS and want to avoid building on a changing API, I would pass on ECS for this project.

    This is kinda a noob question: but if we add/remove mesh at runtime, we can't use Static Collider, right?

    True, I haven't benchmarked using compound collider, my intuition is to avoid gameobjects because I already did with rendering, but that could be wrong... I really wish there is a more lightweight "gameobject" (and I know ECS has that, but alas...)

    I am curious about this one, you mean compound collider right? Are they all moving? Are they mostly static?

    My baseline is laptop computers but they should have decent CPU nowadays.
     
  13. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    My compound colliders example. I use ECS here. But colliders are still on GameObjects using PhysX. Colliders are visible on the video, as green gizmos, when I move quickly objects.


    Static colliders are baked.

    But Dynamic colliders have sleep method. Which is automatically handled. That allows to save on calculations.
    Compounds colliders are handled a little different, but by much.
     
  14. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    One gameobject with several colliders
     
  15. ShilohGames

    ShilohGames

    Joined:
    Mar 24, 2014
    Posts:
    3,015
    When I go purely the DrawMeshInstanced route, there are no GameObjects for the individual units in the scene. So any movement and collisions are handled manually by my own code. I create a class I call an Instancing Pool. My instancing pool contains an array of a custom struct to hold all of the information about the units in the scene as pure data.

    Doing an instancing pool for a bunch of lasers is easy. Each laser unit will scan forward a small amount each frame using a raycast to see if the laser will hit any objects in the scene. And lasers do not have to check to collisions with other lasers.

    When things get more complicated is when trying to build an instancing pool for units that do need to accept collisions. For example, if you want to make a massive asteroid field with thousands of asteroids floating around in the scene, then you would need to manually implement basic collision detection functions into the instancing pool class. The units would need to check for collisions with each other and expose a public function so other objects in the scene can ask the instancing pool if those objects would collide with any units in the instancing pool.
     
    bitinn and Ryiah like this.
  16. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    Is this actually worthwhile? Naive implementation will end up slower than just using game objects.

    I'd think that you would need to be extremely careful, deliberate and skilled to make this worth your time.
     
  17. ShilohGames

    ShilohGames

    Joined:
    Mar 24, 2014
    Posts:
    3,015
    It depends on the implementation. Using a purely data oriented approach like instancing pools using DrawMeshInstanced can result in massive performance benefits when handling many thousands of active units in a scene. It outperforms GameObjects by a huge margin in that case.

    For the lasers in Disputed Space, my instancing pool design outperformed object pools by a factor of about 6x. I have scenes with 10,000 lasers flying around with triple digit frame rates on PC. That was a game I released on Steam in 2017 that I built in Unity 5.5, so this was before ECS was available.
     
    Ryiah likes this.
  18. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    Thats pretty interesting - just watched the video - yeah you have a ton of lasers flying around. It's an interesting example cuz the lasers themselves dont need collision. So yeah, you can just raycast against the ship colliders without needing to do all that stuff by hand. Smart.
     
    ShilohGames likes this.
  19. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    Thx for sharing your method, this is kinda what I had in mind, I think my problem is slightly more complex as it's a player-controlled character colliding with walls and large in-world objects, it's basically collision prediction with non-constant speed/acceleration/direction.

    By the way, does your ship use GameObject and Collider? If not I guess you have to store and check against AABB (Bounding volume).
     
  20. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    I would take a step back, throw out any assumptions not based on actual testing. Do you know the performance difference between DrawMesh* and just having gameobjects in your project not just theory?

    Start with the simple approaches first. Gameobjects with colliders and good LOD will take you a very long ways. Much further then you are thinking it will I guarantee that much.

    Optimizing rendering and colliders starts with modeling and good design. Looking for ways to standardize/modularize so that you can use simple primitives colliders, etc..
     
    Antypodish likes this.
  21. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    I agree. It is Time to stop theoretizing and start to actual do some tests. Then probably will realize soon that collided are least of problems to worry, for open/large worlds.
     
  22. ShilohGames

    ShilohGames

    Joined:
    Mar 24, 2014
    Posts:
    3,015
    There is no reason to use DrawMeshInstanced to render the player. There is typically only one player in the game, so just use a GameObject for the player. Even if you had 2-8 local players, you could still get away with using a GameObject for each.

    Where DrawMeshInstanced is absolute magic is when dealing with thousands of identical units moving around in a scene.

    In Disputed Space, the player is on a GameObject. The lasers are handled by an instancing pool using DrawMeshInstanced.
     
    bitinn and Ryiah like this.