22
votes

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

7
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
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
Looking at your generated mesh, is it not possible to use LineRenderer's to achieve such an effect?Hristo
@Hristo Maybe it will be possible to use LineRenderer but how this can help in collisions?seek
@seek Well you could detect if your GameObject/Player is touching the line or has touched the lineHristo

7 Answers

1
votes

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.

0
votes

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!

0
votes

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/

0
votes

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.

0
votes

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.

0
votes

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.

0
votes

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.