0
\$\begingroup\$

I'm learning 3D game development with some kind of mini golf game.

It is working well so far: I have a sphere, and I am using AddForce on its RigidBody to launch it in the desired direction.

One feature I'd like to add is to show a preview line that predicts the trajectory of the ball. Like telling the player that if he uses this direction and this force, the ball is going to follow this route, collide here, bounce, and end up there etc.

I know how to use a line renderer alright, but I don't know how to calculate the array of points from which to draw the line.

It has to be updated in realtime, and the player can quickly change the potential direction and force at any time - it has to consider that there are various objects with different bounciness/friction etc.

That seems like a lot of work. The only thing that occurs to me is to use dummy invisible balls that will be constantly firing using the potential direction/force and then recording their route, but I'd need to figure out some way to make them 'move faster' so I can get the array of points instantly.

What would be my best approach for this?

\$\endgroup\$
1
\$\begingroup\$

Your simplest approach would be to simply run the physics math yourself. The term to google would be "projectile motion". Its not to much more complex than algebra and vector math. You would simulate the initial condition and then iterate over the path to create points to then graph.

If that is not your cup of tea, you could send the invisible ball and graph it as it goes. I would build over time so it actually might be a cool effect.

\$\endgroup\$
1
\$\begingroup\$

A physics simulation is not (should not be) bound to real-world time in any way. I don't know how Unity does it, but a physics solver should have a function like "Simulate [timedelta]". Nothing should prohibit one from calling that a thousand times from within one single visual frame (main loop, game frame), with an estimated (average?) future time delta. It's a computer, it is able to execute a thousand physics simulation cycles in practically zero time.

Between each game frame, reset all relevant physics bodies (copies of them?) to their original, static positions and redo the (hidden, parallel) simulation as the user aims. No need to record all intermediate positions of that single ball (nm the others), every 10th should be enough - this means 6 recorded positions per second if 60 fps - will make a smooth curve to paint.

Having said that, i wonder if your idea is good. First, it removes the challenge - what's the point if the user sees the result all time? Second, the ball (its recorded path) will probably be weird as it will make unexplained turns from upcoming collisions that you cannot show the user without showing a complete pre-simulation of the entire game board.

At least limit the simulation/hint to the first or second hit with another ball, or 1-2 seconds, or whatever feels right.

The determinism of physics simulations is popular discussion subject. For various reasons, assume it is not deterministic, ie. as you launch the visual simulation, the balls will not always move as shown in the pre-simulated preview. This is another reason to not make the preview too long.

Also to note, a pre-simulation calculated in another way will not match the result of your current physics solver. A solver is not exact. It presents something that looks good enough but another solver/method will probably disagree. Hence, you must use your current solver, the same that eventually does the final, visual simulation, so handle this task.

\$\endgroup\$
0
\$\begingroup\$

Unity usually treats one unit of world space as one meter. Also, gravity should be close to actual Earth gravity, -9.81 m/s^2. To be sure, you can check in the Physics Manager. Assuming you know the initial x and y velocity of your projectile, you can trace its parabolic path like so:

//x0 and y0 are the initial position components, in meters
//vx0 and vy0 are the initial velocity components, in m/s.
//t is the time from the initial launch, in seconds
//g is gravity, probably -9.81 m/s^2
x = x0 + vx * t
y = g*t*t/2 + vy0*t + y0

Now, loop through this plugging in different values of t and you should get your path. The problem, though, is that this doesn't account for bouncing off obstacles. One possibility, although I'm not sure if it will have perfect accuracy, is to check with each iteration of your path tracing if the point lies within a surface. If it is horizontal, invert the y velocity, multiply by a scale for its bounciness, and the set that x and y as the new x0 and y0 for the next iteration. If the wall is vertical, do the same, but inverting and scaling vx. It might get a little trickier if some of the obstacles have diagonal surfaces, but you could still do it using dot products.

If this still doesn't work, you could always send a test ball through at an increased timescale to gather the needed data.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.