- Home /
Get Rigidbody Time to Destination.
Hey how's it going,
I am working on a physics based game and I have recently gotten some code that will rotate my character based on how long it is in the air and it will always land on a flat side, but to do this, I need to calculate the time to the destination. Because I am setting the velocity of the via
rigidBody.velocity = new Vector3(rigidBody.velocity.x,jumpForce*jumpForceMultiplier,moveSpeed);
is there anyway to calculate the time it will take for the object to hit the ground? I have a ground check method that is just raycasting to the collider bounds +0.1 to check of the player is on the ground, if that helps.
Thanks.
Just to clarify because I believe I was unclear. How can I calculate where the player will land when they either go off of a ledge OR jump based on the velocity, AND how long it will take them to get there?
Sorry if I was unclear
That is not easy to calculate, AFAI$$anonymous$$. Depends on the trajectory of the player (straight line or parabolic), how far the colliders are from the player, what's the player initial velocity, gravity, drag, ter$$anonymous$$al velocity. And even with all of that, you're still not ensured you'll get an accurate result because physics in Unity are an approximation at best.
Thanks Arkaid, here is some background information on the game, it is a 2.5d game, the camera angle is fixed but is using 3d graphics, so the trajectory will always be straight, and other than that, is there a way to make my player 'jump' so that I can know how long it will be in the air?
There are some equations to calculate time of an object in freefall, so I'd start looking there. But I think simple is better: If the length of the jumps are more or less the same all the time, just measure the time it takes to make them ;)
Is it possible to calculate the time taken if you have the starting position, a target position and the velocity?
vector direction = end - start;
vector distance = magnitude(direction);
float speed = magnitude(velocity);
float time = distance / speed;
Unfortunately this won't work because if I wanted to make the rigidbody actually move into the air, then I must set the target vector above where it needs to land and then it won't calculate when it will hit the ground correctly. Thanks. Feel free to correct me if i am taking this the wrong way.
Answer by Eno-Khaon · Jul 11, 2016 at 05:18 AM
A trajectory can be calculated at any given time. Your current velocity can be used to simulate upcoming physics to predict where you will hit the ground.
I included a large number of formulas in a previous answer, so they can be used in conjunction with Raycasts for a simple test for where the center of a collider would reach. The more accuracy and reliability you want, the more expensive the calculations will become.
Thanks alot for these, but how would I use them in my controller, if I want my character to go into the air, then I must set the y value to be above where I want it to and, which basically voids any attempts to calculate time because the target vector is not on the ground, and it will take more time for the object to fall onto the ground. Am I misinterpreting the answer?
Well, my previous answer didn't include absolutely everything...
The idea is that from any initial position with any initial velocity, you can deter$$anonymous$$e how long it will take to reach the ground by:
1) Recreating the physics timesteps.
rigidbodyDrag = $$anonymous$$athf.Clamp01(1.0f - (rb.drag * Time.fixedDeltaTime)); // Per FixedUpdate()
// This means that if your drag is equal to the framerate of FixedUpdate(), your object will lose 100% of its speed every frame
velocityPerFrame = lastFrameVelocity + (Physics.gravity * Time.fixedDeltaTime);
velocityPerFrame *= rigidbodyDrag;
positionPerFrame += (velocityPerFrame * Time.fixedDeltaTime);
That is the general process by which the position is deter$$anonymous$$ed by the combination of physics velocity and drag.
If you already know your initial/current velocity (i.e. movement at any time whatsoever). you can simply use that as your starting point and simulate physics from there.
2) Check for the ground.
This is where the use of Raycasts comes into play. Fire a Raycast from the current point of calculation along its current velocity/frame distance (or from the previous point to the current one, if all the data's being retained). If the Raycast hits something, then you have the bare $$anonymous$$imum possible outcome for a collision. Again, more complex collision tests can improve accuracy at a much greater cost of calculation.
... And that's pretty much it.
It's really just a two-step process (Albeit a fairly complicated first step). The time when the collision will occur is deter$$anonymous$$ed by the number of physics timesteps which have been tested. For example, the default Time.fixedDeltaTime is 0.02, for a total of 50 physics calculations per second. With that in $$anonymous$$d, count the number of timesteps until the Raycast contacts the ground.
// A very rough approach
if(Physics.Raycast(positionPerFrame, velocityPerFrame.normalized, velocityPerFrame.magnitude * Time.fixedDeltaTime))
{
totalTime = elapsedTime;
}
else
{
elapsedTime += Time.fixedDeltaTime;
}
Wow thanks alot for the really detailed response, I am just a little confused as to how I would put this into a single method for example. Sorry if I sound a bit confused, but I have been developing backend java applications for a while now and I am only just stepping back into Unity, C# and front end stuff in general. Thanks again for the amazing response.
Your answer
Follow this Question
Related Questions
Need help with the physics and angles of gerbils in a plastic ball.. 2 Answers
ForceMode.Acceleration estimated dst != covered dst with a single Addforce in effect 1 Answer
Need a math geeks help. point at which a line hit a plane 1 Answer
Drawing projectile trajectory 5 Answers
How to calculate the angle of a trajectory to hit the target 1 Answer