Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.67k stars 250 forks source link

I noticed some collision issues with the automatically generated voxel collisions #121

Open CammiePone opened 4 years ago

CammiePone commented 4 years ago

For whatever reason, the collisions for the cube voxels seem to not collide with the player's collision box correctly. You sort of sink into it, and that causes some shakiness when you get pushed out of it, which is a bit annoying to see. It collides decently when going straight against the cubes, but when you collide with corners (whether turned at an angle, or walking at an angle), it gets a bit janky.

I'm wondering if this has to do with the fact that all voxels, whether cubes or not, have the triangles making up their faces? It just seems weird that it would act like this with the ones generated by Voxel Tools, and not with other collisions in Godot.

Here's a video of the comparison: https://www.youtube.com/watch?v=-v3hN6hIcRM

Zylann commented 4 years ago

That would be a problem of the physics engine you are using (GodotPhysics or Bullet). Collision shapes generated by this terrain are mesh colliders. It looks like your FPS demo uses box colliders, which could explain the difference? Notably, I would also recommend to use a capsule shape or a cylinder instead of a rotating box, hard edges can be really nasty.

An alternative is to use Minecraft-like physics with the VoxelBoxMover helper for collisions with the terrain (which is actually equivalent to not rotate your box). Just like Minecraft it is limited to AABBs and bypasses classic physics engines completely, however it makes the map generate faster since it doesnt need any collision shapes and has no physics_process constraints.

TokisanGames commented 4 years ago

FYI, In my demo I use a raycast collider for both smooth and blocky collisions. This allows my character to navigate over both terrains without getting stuck at each block level.

CammiePone commented 4 years ago

That would be a problem of the physics engine you are using (GodotPhysics or Bullet). Collision shapes generated by this terrain are mesh colliders. It looks like your FPS demo uses box colliders, which could explain the difference? Notably, I would also recommend to use a capsule shape or a cylinder instead of a rotating box, hard edges can be really nasty.

An alternative is to use Minecraft-like physics with the VoxelBoxMover helper for collisions with the terrain (which is actually equivalent to not rotate your box). Just like Minecraft it is limited to AABBs and bypasses classic physics engines completely, however it makes the map generate faster since it doesnt need any collision shapes and has no physics_process constraints.

Well I'm using Bullet. GodotPhysics is waaaay worse when it comes to this issue. As for hitbox rotations, I'm currently using a non-rotating rectangular hitbox, but I intend to use multiple hitboxes that map to the model, which would act in a similar way to having a rotating rectangular hitbox (hence why it's a problem I thought I'd bring up). I also kind of want to have actual physics calculations for blocks, so limiting myself to AABBs won't really do...

I'll see if I can figure out Tinman's raycast collision method. I'm still relatively new to Godot (I actually come from Minecraft modding), so I'm still getting used to everything in the engine ^^;

EDIT: Unfortunately, the raycast collider method doesn't fix the jitteriness when colliding with concave corners.

TokisanGames commented 4 years ago

To clarify, I'm using the raycast collision shape on my player.

By shakiness, you mean you push the character against the wall and it allows you to push in a bit then it pushes you back out, instead of just stopping you cold?

What if on your modeled environment, you remove the collision shapes, then click the meshes, click the mesh menu, and select create trimesh static body? That should give you the same collision mesh Voxel Tools uses.

https://godotengine.org/storage/app/uploads/public/5ca/e75/a58/5cae75a58c4de440986887.png

CammiePone commented 4 years ago

To clarify, I'm using the raycast collision shape on my player.

By shakiness, you mean you push the character against the wall and it allows you to push in a bit then it pushes you back out, instead of just stopping you cold?

What if on your modeled environment, you remove the collision shapes, then click the meshes, click the mesh menu, and select create trimesh static body? That should give you the same collision mesh Voxel Tools uses.

https://godotengine.org/storage/app/uploads/public/5ca/e75/a58/5cae75a58c4de440986887.png

Well that is the shakiness I mean, and you're right, it is the same collision mesh as the rest of the voxels, and yet it's not doing the shakiness. Even the slope is perfectly fine.

TokisanGames commented 4 years ago

I made three rectangular solids to form a corner and generated a trimesh static body (as voxel tools does). This generated triangles on the flat surface of the collision shape. I noticed the jitter when pushing my character into the corner at some angles. Then I changed those collision shapes to boxes and the jitter went away.

This is with me using a raycast collision shape, which looks like a cyllindar up top and an arrow (raycast) down below.

So a workaround might be to patch VT to provide box collision on blocky terrains and trimesh shapes on smooth terrains. Or you could unselect the generate collision checkbox and generate your own. But as Zylann said, the cause is upstream in Godot. You could file a bug report on the main repository, but you'll need to create a sample use case that does not rely on Voxel Tools as I just did. You'd have two scenes, or two scenarios in the same scene showing one that works and the other that doesn't. They might just be able to fix it in the move_and_slide function.

CammiePone commented 4 years ago

I made three rectangular solids to form a corner and generated a trimesh static body (as voxel tools does). This generated triangles on the flat surface of the collision shape. I noticed the jitter when pushing my character into the corner at some angles. Then I changed those collision shapes to boxes and the jitter went away.

This is with me using a raycast collision shape, which looks like a cyllindar up top and an arrow (raycast) down below.

So a workaround might be to patch VT to provide box collision on blocky terrains and trimesh shapes on smooth terrains. Or you could unselect the generate collision checkbox and generate your own. But as Zylann said, the cause is upstream in Godot. You could file a bug report on the main repository, but you'll need to create a sample use case that does not rely on Voxel Tools as I just did. You'd have two scenes, or two scenarios in the same scene showing one that works and the other that doesn't. They might just be able to fix it in the move_and_slide function.

Hm... okay, guess it just didn't want to jitter for me when I tested it (maybe because all my boxes were taller than the player?). As I don't know C++, I guess I'll figure out how to generate my own collisions, and I'll go ahead and my a bug report on Godot's repo explaining the problem to them. Thank you both!

EDIT: just out of curiosity, where would the collision box be defined in a script? At first I thought in the voxel itself in the voxel library, but I don't see anything about collisions.

Zylann commented 4 years ago

If you want to create a collision box for every voxel, your CPU will die. At least you'd want to create one for each having a visible face, which is still a ton of them. And still, after the custom_blocky_mesh branch is merged, blocky voxels won't necessarily be cubes (although great majority will).

To create nodes in response to blocks getting loaded, you'd need https://github.com/Zylann/godot_voxel/issues/99. However due to how expensive that would be for each visible voxel, it might make more sense to implement this in C# or in C++. And yet, I believe this would deplete performance a lot because of the amount of box colliders to create. It needs to be investigated to see if that's the case, before considering it an option. (but really I think mesh colliders need to be fixed (or move_and_collide?). Fuckton of games use mesh colliders.)