22

I'm working on game where user generating mesh in runtime (all the time) so mesh have many vertices and in the same time there is a GameObject - player that need to trigger event when it is in area of this generated in runtime mesh.

Camera in this game is 3D, but this generated mesh is flat. In my attached drawing I show this in top view to better show how it looks like.

Now I'm updating Mesh Collider every few seconds, but it is very slow after generated mesh have more and more vertices.

I believe that this is very simple method of collision so maybe there is any other method to detect this instead of Mesh Collider attached to dynamically generated mesh?

UPDATE #1

I know that Mesh Collider is very slow and should not be updated in runtime. I also know the idea that should use primitives like box collider.

But in this situation when this flat mesh in updated every second (and it grow) it will be thousands of box colliders and new need to be added every second. This method will also not work.

UPDATE #2

My second idea is to find nearest triangles to player and create colliders for them (box colliders should be fastest). But I really have no idea where to start or it is even possible ? Someone ?

Drawing 2, as an answer for @Hristo

Drawing

seek
  • 1,065
  • 16
  • 33
  • I don't know what to suggest for your situation, but yeah, you do NOT want to be updating a mesh collider *at all* (rotating, scaling, and translating also are a problem). For exactly the reason you came looking for help: it's expensive as hell to recalculate. – Draco18s no longer trusts SE Apr 24 '17 at 21:36
  • Yep.. I know.. :(. Using box colliders instead is also not a solution because it will be thousands of box colliders after some time and I think that it will be also not good for performance :/ – seek Apr 24 '17 at 21:39
  • Looking at your generated mesh, is it not possible to use `LineRenderer`'s to achieve such an effect? – Hristo Apr 25 '17 at 05:35
  • @Hristo Maybe it will be possible to use LineRenderer but how this can help in collisions? – seek Apr 25 '17 at 06:37
  • @seek Well you could detect if your `GameObject`/Player is touching the line or has touched the line – Hristo Apr 25 '17 at 07:16
  • Could you please define what your mesh exactly is? Is it a sprite with the pattern above (red/white)? or something else.. – Hristo Apr 27 '17 at 08:45
  • I actually didn't programmed it and didn't tryit, have you tried thinking to chop the mesh? – Cristiano Soleti Apr 27 '17 at 09:58
  • @Hristo Drawing above only showing how mesh can look like. It is generated from the script like a never ending snake, Snake move in random directions, sometimes overlaping himself. (flat on Y dimension). I'm just anding 2 vertices and triangles every 60 frames and I'm rebuilding mesh, and meshcollider. – seek Apr 27 '17 at 15:26
  • @CristianoSoleti I tried this also, but thousands of small gameobjects with meshrenderers and meshcolliders also have slow performance. I don't know if frustrum culling in unity culling also meshcolliders or only renderers? – seek Apr 27 '17 at 15:27
  • If you are making Vertices that means for sure you have lines between them, which means you could check if your `Player` is intersecting with that line. – Hristo Apr 27 '17 at 18:09
  • @Hristo Simple intersection with line will not work because I will not know if player is inside (on top of the mesh) or outside the mesh. I thinking maybe I can somehow detect overlapping of meshes without collisions? – seek Apr 27 '17 at 18:30
  • If your player is a `Cube` as in your picture, you could say you have 4 x `Vectors` that represent the edges of the `Cube` and if at any moment one of them intersects with the boarders of your "snake" that means it is outside. – Hristo Apr 27 '17 at 19:19
  • @Hristo I just add another image please check. Player is a Cube, but "snake" can overlap itself. In this situation when I will do intersection test it will tell me that player is outside :( – seek Apr 27 '17 at 19:44
  • Can areas of your snake be revisited once the Player passed them? – Thomas Hilbert Apr 29 '17 at 14:55
  • There is no magically easy solution. Depending on how and why the mesh is generated you can use different work around solutions. A first approach - still using colliders directly - is to use the box collider like you thought but in a smart way: make sure each collider is in a separate game object, have a set granularity for the boxes treating them like voxels on a grid, only add new box when that grid section gets covered by a new triangle for the first time, consider joining adjoining filled voxels when possible. – FrankM May 03 '17 at 07:28
  • You should "link" vertices with area. In this [Image](http://prntscr.com/f3n8xh) you can see that I sliced by area. Each black square are only `meshRenderer` while blue square are both `meshRenderer`and `meshCollider`. Blue are defined by the pink bounds which follow player position. In this case, there is only 4 collider. And you have to update *only* where it's change. – Alaanor May 03 '17 at 14:18
  • Why not instead of creating the box colliders, however you're doing that, you instead create reference points with all of the data needed to create those box colliders, then load and unload the box colliders based on the distance from player, so instead of having way to many box colldiers. You would only need the center point of them and the necessary scale data. So yes you do create a lot of box collider reference points and only create them if you haven't done so already and on top of that you don't have thousands of box colliders active at the same time. – Dan Flanagan May 03 '17 at 19:28
  • The player can go back in the mesh or only forward? Cus if he only goes forward you can delete the parts that the player have already passed by. – Magrones Jul 25 '17 at 02:23

7 Answers7

1

If mesh colliders work for small sections but not the full length, generate multiple mesh colliders, breaking off a new one every X number of polygons or X length of path as the player draws a longer path.

Semimono
  • 664
  • 1
  • 6
  • 14
0

You could use raycasting – it normally requires a collider, but I found this (script for raycasting on mesh, without colliders), which I believe you could use in your case.

You could then introduce an invisible background to your generated mesh, and use raycasting to detect what gets hit first. If your player will remain square, you can cast a ray from the 4 corners, and if all 4 rays hit the mesh, you know you're on top of it.

In the case of the overlap, since the code from the link can detect multiple triangles hit by the same ray, if the number of triagles hit is bigger than 1, you know you have an overlap. And you could probably use the order as a z-index of sorts.

I haven't tried the code, but it seems to have worked for others. Hope this helps!

mnen
  • 33
  • 8
0

if you want dynamic mesh Collider, you have to use other physic engine,

if you destroy unity mesh collider component, or change the sharedMesh of that component, its performance is very bad, because the physic engine has to rebuild the whole new MeshColldier.

you can look this article:

https://forum.unity.com/threads/shadow-of-the-colossus-deformable-mesh-collider.519900/

liyonghelpme
  • 67
  • 1
  • 5
0

You shouldn't use any collider in your circumstance. It seems you are using a 3D camera doing a 2D job.

What you need is:
1)Draw the created meshes to a 2D picture.Draw the meshes from a second orthogonal camera to a RenderTexture, by filtering the tags, you got the top viewed picture that only contains your meshes.

2)Then you can use this map to calculate the collision with your character:
Graphics.Blit the image in size of your character to the RenderTexture. You should write a shader that accepts two textures, one is the map and the another represents for your character, draw the character to your map, mix the two colors to a special color in your shader. In the end, you got a mixed texture, you scan the texture and find out any special color in it and do the job you want next.

Simon
  • 647
  • 4
  • 9
0

Would I be right to assume that this is a kind of racing game where one player creates the race track? I've actually attempted something like that before. In my case, I created a "Track Segment" object, basically a flattened cube object, every frame. Which is lazy I admit, since it's creating a new box collider every frame. However, I never experienced any performance problems in this way.

Here's what it looked like.

My suggestion, then, is to split your mesh into smaller game objects. As you described, it seems that performance gets much worse with more vertices, in this way you'd keep vertex counts low.

Iurii Tkachenko
  • 3,106
  • 29
  • 34
Roy C
  • 11
  • 2
0

A voxel-based solution is the answer here, clearly.

As for how to implement one, I can't give you details because, although I know what the answer is in general, I have never implemented a Voxel engine myself, and neither have I used any existing one. So I can only point you in the right direction.

Basically, instead of trying to create the mesh from arbitrary points, you create it from fixed, finite, easily-optimizable ones. It's how Minecraft, and even more complex games, do it.

Sebastian Lague has a video covering some of the core stuff related to the mesh-generation in this video.

CosmicGiant
  • 6,275
  • 5
  • 43
  • 58
0

Of the may ways to tackle this it might also be an option to not use any collider but create your own implementation of testing against edges in FixedUpdate of your moving objects. If they are not too many, this might be faster. Then you can also specify how to behave if the changing of the geometry suddenly causes a player to be out-of-bounds.

Downside is having to deal with things like bounciness, damping yourself.

Blindleistung
  • 672
  • 8
  • 21