0 votes

UPDATE: I've edited this post with my solutions at the bottom. Thanks to MysteryGM. Also, check out this thread I made on Reddit asking the same question.

I am working on a 3D minigolf game and have created a level with some ground and a castle (using the Kenney texture packs here ). The main issues I’m faced with are:

  1. Hitting the ball with any considerable force causes collisions with walls to not occur;
  2. The ball physics are very strange (e.g. weird and unexpected rolling behaviour – more on this below)

The ball is created as a RigidBody, scaling left at (1, 1, 1), default mass and gravity.

Update: I have also tried by enabling Continuous Collision Detection (Continuous CD) and it does not fix either of these issues.

Files
Here is a link to the entire project.

Issue 1: Collisions
The ball seems to not collide with objects if it is moving relatively quickly. See this gif here as an example:

Ball going straight through the castle

You can recreate this issue yourself by holding in left click and move the mouse forward to increase power and shoot in the direction of the bar that grows out from the ball. Aim at the castle, and release left click. You’ll see the ball go flying through the castle, no collision/bouncing off the castle walls that you’d expect.

Issue 2: Weird ball behaviour

The ball movement is really odd and not natural in some circumstances. The most frequently occurring issue is the ball rolling for a long time in a fairly unpredictable way. Here is a gif I’ve captured of a low power shot towards one of the mounds, the ball moves up and down the mound in a fairly natural way, but then it just circles on the flag ground for a long time in a really unnatural way. I’m not sure what I’ve done in the project to result in this behaviour – the ground is totally flat from what I can tell. Here are a couple of examples of the ball movement i'm talking about:

Weird ball behaviour: ball path is strange after rolling back down the mound - wanders aimlessly for a bit before coming to rest
This one shows the ball taking a fairly strange path after rolling back down the mound - it appears to wander aimlessly for a bit before coming to rest

Weird ball behaviour: ball keeps rolling after you would have expected it to stop

This is my first time using Godot, so if you notice anywhere we could improve (antipatterns I’ve used, optimisations I could make), I’d love to know about them!

EDIT - SOLUTION:

With regards to issue 1, following /u/fuzavella's suggestion and increasing the physics FPS seemed to help reduce the collisions being missed at high speeds (keep in mind that there is a performance trade off). As of Godot v3.0.6, you can change the physics FPS in the editor by going:

Project > Project Settings > General > Physics > Common > Physics FPS

With regards to issue 2 (the continuous ball rolling and weird motion): The ball never stopped because (as far as I can tell), damping on the RigidBody for the ball was set to -1. I thought because friction was set to maximum that this would be enough, evidently not. Changing the damping of the RigidBody to some positive value seemed to make the friction take effect.

in Engine by (17 points)
edited by

1 Answer

+1 vote
Best answer

Issue 1: Collisions

Computers are simple things. It is impossible for a object to "move" in a computer, instead a object "jumps" from point to point. The faster the object moves, the bigger the jump.
Physics engines try to get around this problem with many tricks, like fast small jumps between big jumps. However this only works when you use the proper functions.

solution:
Check that you are using func _physics_process(delta): instead of process(delta): Also check Continous Cd on the rigid body. Also use the proper calls like moveand_slide() instead of your own movement.

last you can use simple raycasting if you know a object is going to move fast, then fake physics with kinematic body.

Issue 2: Weird ball behaviour

Again, computers are very limited things. You can't simulate physics with just a little home PC; even all the computers in the world couldn't do it.
Because complex physics math isn't possible, physics engines fake it. Like Brownian motion, noise is used to simulate it and can cause what you are showing here.

Solution:
Use damping, friction and sleep.
Both Linear and Angular velocity have a damp value. It will slow the object down over time.
Adjusting friction will require a physics material. It will also slow down the object.
Sleep, this is a threshold value that if a object is under it the physics is set to sleep. This stops the object from moving till a new physics force is used on it.

This one shows the ball taking a fairly strange path after rolling back down the mound

No this one is actually colliding correctly. I assume what you find "strange" is that it doesn't mirror it's collision at a angle like this:
enter image description here
That is because this kind of collision rarely happens in the real world.
This type of collision only happens in the real-world when 2 spheres collide. Having only one point of contact you get a mirror reflection of force.
Here is a article on it: https://www.real-world-physics-problems.com/physics-of-billiards.html

Something else. In Pool there is the Mirror Aim Line
enter image description here
Here we can see the force would reflect 45 degrees from the direction of travel, sliding along the wall.
That is indeed what happens in your gif Except, the ball tries to slide against the wall, then bounces off the wall again. (Watch it frame by frame)
Ironically it is off by +/- 10 degrees in the end, very accurate for game physics.

To get the mirror you are expecting, you need to be moving almost directly towards the flat surface. It works something like this:
enter image description here
In short, the wider the angle the less it will reflect as expected.

https://www.youtube.com/watch?v=s_8Mu0lIyFg

by (1,480 points)
selected by

This is a well thought out answer, i'll follow up on those links and extra resources after work.

Check that you are using func _physics_process(delta): instead of process(delta): Also check Continous Cd on the rigid body. Also use the proper calls like move_and_slide() instead of your own movement.

Checking Continuous CD didn't really do much to fix my problem, unfortunately (it is now on, though). I'm also not using move_and_slide() at all, I thought apply_impulse()would be the more appropriate function here as we are trying to simulate a putting action, which appeared to be a good candidate for an impulse function. High speed shots are still causing the ball to go through objects. I've been doing some research (see this thread for instance). I might try those suggestions, though i'm not entirely sure how to make the walls thicker like one user suggested - is it the walls of the model or walls of the collision mesh? Can we manually draw out the collision mesh or is this always taken care of for us by Godot?

Use damping, friction and sleep... adjusting friction will require a physics material.

It appears that part of my issue is that there doesn't appear to be any friction between my ball and the ground. In the course of writing this post i've played with the damping, small positive values for damping appear to make the friction take effect.

Here's what I think to be the relevant settings for the ball (changing damping to a small positive value instead of -1 appears to help):
enter image description here

I don't know what a physics material is however. I've done a quick Google search and I can't find much useful to help me here. I'm aware of SpatialMaterials and ShaderMaterials though. Where can I read more about Physics Materials?

This may be answered by reading over the resources you linked, but if I wanted to pursue a more billiards/pool-like physics system, should I be making use of raycasting and altering the physics programatically (is this even wise?), or is there inbuilt functionality in the engine to achieve this?

I appreciate the feedback you've already given me so far!

is it the walls of the model or walls of the collision mesh?

that would be the collisions. A smart trick for walls that only one side can be collided with. You can make it as thick as you want with no visual indication.

When a physics collision hits the inside of the wall, it will jump to the outside, where the collision should have happened. Visually it will just look like it hit the wall.

Can we manually draw out the collision mesh or is this always taken care of for us by Godot?

Yes you should use manual shapes. In Godot you fist add a type of body (Static, Rigid, Kinematic) Then you add a shape. Like this:
enter image description here
1.) (arrows on the left) Notice that my static bodies, can be a child of the mesh. But for the Rigid body, the mesh must be the child.
2.) (arrow in the middle) here we can see how I made the collision shape bigger than the wall. The blue lines is the collision shape.
Also (not visual here) the floor is also a box, this way it is harder for things to fall through the floor.
3.) (arrow at the castle) Notice I have two blocks in a V formation, to make the doorway, two on the side. This is more effective than trying to collide with the mesh.

There is 3 main physics shapes. Sphere, Box and Capsule. These 3 shapes collide better than any other shape, because the math for there physics is the fastest.

The boxes I used here gives better collision and is faster than trying to collide with the mesh. The downside is I had to add one by one, it is very slow work.

This image is from the old Unity manual, but it is a good example of how collisions work in games:
enter image description here

I don't know what a physics material is however.

Don't let the name fool you, it is just a bit of extra settings that describe how physics objects should react.
enter image description here
So it isn't a real material, but a bunch of settings. It is called a material because it describes how materials react. For example rubber is bouncy.

You can also Right_Click in FileSystem widget. Then select New Resources -> Physics Material.
This way you can create one wood material and re-use it when you have more than one wooden object.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.