- Home /
how should the acceleration of an object sliding down a slope change over time?
The net force accelerating the object down the ramp is the difference between the component of the refrigerator’s weight along the ramp and the frictional force (normal force friction) opposing it, all divided by the mass. (You know, because F = ma). With a simplified equation, is this: gravity ( Sin(angle) - Cos(angle)frictionalCoefficient). This is what am doing (gives 3.6269... acceleration with a 30 deg. angle), but the final velocity should be around 4.66 if the slope is 3 meters long according to this formula: Vf squared = 2acceleration 3. I wanted to make sure everything was working perfectly, so I tried it on scene, but the final acceleration is around 5.89.
void Update()
{
if (!isGrounded || angle > 0)//if the player is walking on slopes or is not on the ground
{
currentGravity += gravity * Time.deltaTime; //positive value (it starts being 9.8 in this example, but it should be 0).
}
if (angle > 0 && angle < 90)
{
if (isGrounded)
{
float frictionCoefficient = 0.15f;
float acceleration = currentGravity * (Mathf.Sin(angle * Mathf.Deg2Rad) - Mathf.Cos(angle * Mathf.Deg2Rad) * frictionCoefficient);
float moveDistance = acceleration * Time.deltaTime;//all of this is a test. Currently always moves right, but it should change depending on the slope.
movement.x = Mathf.Cos(slopeAngle * Mathf.Deg2Rad) * moveDistance;
movement.y = Mathf.Sin(slopeAngle * Mathf.Deg2Rad) * moveDistance;
transform.Translate(movement, Space.World);
}
}
}
Is this right? I mean, the acceleration will be a percentage of gravity, so I thought to use the current gravity as this value. This because, when jumping, the gravity is slowly building up and doesn´t reach 9.8 until a second in the air. Using 9.8 always in the equation gave too much speed ( if you start thinking about it, when the angle is 90, Sin(90) = 1, which makes sense, because is using the entire 9.8 gravity value; but this is also weird because, like I said, the player doesn´t reach that gravity until a second, and slides down the slope faster than it would descend if it were in the air). So again, what am I missing?
Answer by LOSTSOUL86 · Dec 30, 2019 at 05:20 AM
@Feref2 Hi,
First of all i would rather put it in fixedUpdate - that has constant step per second.
In your code: Gravity acceleration is constant and it is always 9.8 downwards. You shouldn't multiply it by time.
What is changing is the speed of your object - gravity value never changes.
Remove this:
currentGravity += gravity * Time.deltaTime; //positive value (it starts being 9.8 in this example, but it should be 0).
Just put:
currentGravity = 9.8f; //and dont change it
4.66 is correct result. If the speed at the begining of the movement was 0. Remember Gravity never changes its value it is constant. Acceleration down the ramp should be constant.
Also move distance:
float moveDistance = acceleration * Time.deltaTime;//
You need to use formula for motion with constant acceleration: Vtotal=Vb + at and Stotal=Vb*t + a*t*t/2 if VB = 0 then Vtotal=at and Stotal = a*t*2/2
So speed will increase every step Then:
speedTotal = speedTotal + acceleration * Time.deltaTime;
And finaly the distance moved:
moveDistance = speed * Time.deltaTime + acceleration * Time.deltaTime * Time.deltaTime /2;
Just use exactly the same formula you used on the paper.
Also better move it to fixedUpdate and remove Time.DeltaTime. FixedUpdate runs 50 times per second it is good for physics.
Hope this helps.
Thanks for your answer. First, I disabled Unity physics, so FixedUpdate() doesn´t work. Second, I think currentGravity is fine. See, velocity.y(time) = initialVelocity + gravity(time); That formula gives the velocity at the specified time so, for example, if 0.5f is half a second, then currentGravity is 4.9f. Is the same than this: velocity.y -= gravity Time.deltaTime; Which is the velocity that it had before (since the Vo is a constant) $$anonymous$$us the accumulated gravity of this frame. Gravity is not constant, it changes over time. Anyway, now I see that my mistake was only using the acceleration without adding the previous speed (in fact, it works the same as gravity, since 3.6(1 second) and 3.6(1.277777777777) = 4.6). And lastly, why is this neccessary: moveDistance = speed Time.deltaTime + acceleration Time.deltaTime Time.deltaTime /2 ? (by the way, could you explain it?) Shouldn´t moveDistance = speedTotal * Time.deltaTime be enough? I mean, if it´s multiplied by the deltaTime, it should move that distance after a second, so one frame would move the corresponding speed, then the next one use the new speed.
@Feref2 $$anonymous$$y friend, If you want to simulate physics you need to follow physics rules - so first you need to understand how physics works in real world and just copy it into code in order to simulate it. You can set up any other rules in your world but that wont be simulation of real world physics. It will be just some other behavior not existing in real world. In real world Gravity acceleration is constant that is why it is defined as 9.807 constant (for example in Unity) and it doesn't change with time. For same reason you cannot multiply Velocity by Time to calculate the distance moved because that is not the correct formula for the calculation of the distance in this type of movement. As I mentioned before in your example you have the type of the movement with constant acceleration. The formula you used in your equation for moveDistance is for the movement with constant speed - and it is not correct for the object sliding from the ramp (constant acceleration). You solve this movement equation first on the paper and then you see how it works. Those are correct equations: g=CONST=9.807, a=g(sinα-μcosα), V=Vb + at, S=Vt+at*t/2.
I don´t think am understanding gravity now, and the new formula still gives an incorrect motion
void Update()
{
if (!isGrounded)//
{
velocity.y -= gravity * Time.deltaTime;//resets to 0 after collision
}
if (angle > 0 && angle < 90)
{
if (isGrounded)
{
float frictionCoefficient = 0.15f;
float acceleration = gravity * ($$anonymous$$athf.Sin(angle * $$anonymous$$athf.Deg2Rad) - $$anonymous$$athf.Cos(angle * $$anonymous$$athf.Deg2Rad) * frictionCoefficient);
totalSpeed += acceleration * Time.deltaTime;
float moveDistance = totalSpeed * Time.deltaTime + acceleration * Time.deltaTime * Time.deltaTime / 2;
movement.x = $$anonymous$$athf.Cos(slopeAngle * $$anonymous$$athf.Deg2Rad) * moveDistance;
movement.y = $$anonymous$$athf.Sin(slopeAngle * $$anonymous$$athf.Deg2Rad) * moveDistance;
transform.Translate(movement, Space.World);
}
}
}
A Debug.Log shows that the totalSpeed is around 4.7, 4.6, 4.9, and 4.5. Is not even constant, Why is this happening? I also placed a timer that is like this: timer += Time.deltaTime; It should be 1.277777777 (again, 3.6 * that number gives 4.6), but is sometimes like 1.28, 1.24, etc. Again, shouldn´t it be constant? I mean, if the last frame took more time to execute then it would make sense to be sligthly more, but the totalSpeed isn´t constant either.