My bouncing ball won't come back down, why?

I am trying to make my own bouncing ball algorithm instead of using UE physics system (for reasons). However; when the ball hits the ground it will bounce once but then carry on in the opposite direction.
I’ve tried to convert the below Unity algorithm that I found on Youtube to Blueprints.

Gravity is set to -98 and restitution (bounceFactor) is at 0.8.

My blueprint is in a macro that runs on the balls’ tick.


Rather strange method, but should give you a bounce. I just threw it into a project and it worked (ball moves very slowly, gravity is week, and yes it bounces a long way up, but it does come down again).

This was my (cleaned up, but I believe functionally identical) test version, I took the liberty of renaming the acceleration vars to better match how they were being used.

Were you just impatient?

Haha yes indeed I lack patients. I did eventually discover that it was slowing down after printing the velocity.
The other problem that I noticed was the upward motion starts slow then accelerates, the opposite of gravity lol

Can you elaborate when you say it’s a strange method? What would be the best way to achieve this?

Not so strange I guess, just looks funny (two velocity vars, acceleration never stored (which is fine, you don’t need it anywhere else here)) and is missing things you might expect (ball mass, some kind of drag coefficient).

Looked ok to me, everything seems slow though so I wasn’t 100% and I stuck a Print String in there, and mine appears to be behaving as expected; Accelerating on the fall, losing energy on the bounce and slowing (immediately) as it heads back up:

LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = -12.943958
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = -12.971435
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = -12.99845
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = -13.027148
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = -13.054011
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = -13.080815
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = -13.108689
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.460257
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.431664
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.406177
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.378538
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.351231
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.323651
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.296978
LogBlueprintUserMessages: [BouncyBall_bp_C_UAID_047C164D34D4552E02_1746021031] V = 10.269358

Edit: I was just logging the Velocity as calculated each frame by this method, which is not actually the velocity, just the offset each frame. So it is frame rate dependant and not a good test, but I get fairly consistent frame rates so the data probably still good.

I removed the second delta time multiplication and it seems to work much more like what I’m going for now.
I will add in drag soon, I just want to do this in baby steps.
Something weird happens sometimes when I start that simulation, occasionally the first bounce will go higher than the initial drop height. There is a stutter when I press the play button so I’m guessing this is just an UE thing?

While the squaring was wrong if you were calculating the actual velocity (as var name suggests), given that you were actually just calculating an offset it is correct.
cm/s/s * s = cm/s (units of velocity)
cm/s/s * s*s = cm (units of position)

We are not integrating so this solution is always going to be effected significantly by framerate, and the use of Previous Velocity (actually Offset Last Frame) I think makes this worse.

If you are getting a stutter on startup and some really big time deltas, that could easily cause the issue you are seeing. The ‘velocity’ update considers the full time delta and applies it, before checking for ground collision, with a really big time delta the amount of that delta before it actually hit the ground is irrelevant, it will accelerate it as if it were falling the whole time, then the collision handling flips the velocity (which is far bigger than it should have been), which would explain your high bounce.

Stick a conditional Print String in there, log if the time delta is greater than, say, 0.1. If they print when you start, this is your problem.

The variable names and what is actually happening is going to be confusing, so I would recommend you change things so it works this way:

Velocity = 0;
Acceleration = -982; // cm / s^2

Tick(TimeDelta)
	Velocity += Acceleration * TimeDelta;
	Position += Velocity * TimeDelta;

Get rid of Previous Velocity, you don’t need/want that.
Fix your acceleration ( * 100 to get to cm), this is why everything was so slow.

None of this fixes your frame rate interference, to do any of this properly you need to get into some very heavy math (integration, numerical no less), and such a thing in BP would be horrendous (to look at, and also for perf).

If you want good physics, you probably want to re-evaluate the ‘reasons’ you are doing this all yourself :wink:

Ok, so I’ve cleaned it up to how you have suggested which has given me a tidy blueprint, thanks :stuck_out_tongue:

I’m getting two logs of 0.4s at the beginning so this must be the cause of the weird bounce. I think it’s just my system as every project in UE starts with a little stutter.

I’m not making some complicated physics system (I wouldn’t know how to, you’ve seen my maths right? lol). It’s just for a top down soccer game but I didn’t like the way the ball behaved, too random. I want the ball motion to be predictable.

Now, if I can just get the ball to bounce off walls at the correct angle…

You could just delay the start of things to get around the long initial ticks.
A (somewhat) better solution is to ‘substep’ your update if the delta is big:


(moved it into a function to use local vars).

Still framerate dependant and not a good solution if you want (networked) multiplayer.

If you have the surface normal for the wall you would use the vector reflection formula:
Velocity = 2 * Dot(Velocity, Normal) * Normal - Velocity;

Assuming your walls are axis aligned and the centre of the ‘court’ is at 0,0, handling the +/-X walls might look like this:


(but I have no position reset in there, you do want that)

I can’t seem to get a surface normal while the ball has simulate physics turned off. Looks like I will have to do some reading up on normals.

You mention that it’s still framerate dependant. I was under the assumption that multiplying the velocity and offsets by delta time would solve this?

I think you can probably just hard code them, what I was getting at before when I said if your walls are axis aligned, is that you know the normal from the wall you are testing against.
If you are testing for wall collisions in the same manner as the ground, then your walls are definitely axis aligned (purple vectors are the normals):

They are scaled by multiplying by delta time, the problem is that the velocity is updated first and then applied for the whole delta time. In reality of course the velocity is smoothly changing throughout (we need Calculus to simulate that properly, which we don’t want to do here).

So, effectively what we are doing is calculating what the velocity should be at the start of the tick, then applying it for the entire tick delta. If you have the same starting conditions and work through 1 ‘long’ tick Vs 2 ticks with half the delta, you get different results (assuming some acceleration): For the long tick you set velocity once and apply it, for the 2 shorter ticks covering the same delta you calculate the same velocity initially and apply it, but then update it again for the second tick before applying. Assuming there was acceleration, this second velocity will not be the same as the first, and hence the end result will not be the same.

A fixed length update would make it consistent, but UE doesn’t do those.
If you are not planning networked multiplayer, I would just ignore it. If you are, then it is a difficult problem (and probably best solved by not doing the physics yourself).

Well this really screws everything up for me haha
Looks like I need a complete rethink on how I want to do this.