Search code examples
unity-game-engineunity3d-2dtools

Raycast or timing or lag?


So i'm running a test on a raycast physics handler from a tutorial. I am dropping a block from the same height each simulation with the goal to have the block land on top of a flat surface in one smooth motion. Currently, I have raycasts projecting out of the bottom of the box through a skin width with the raylength scaling off the velocity.y as seen below:

rayOrigin += Vector2.right * (verticalRaySpacing * i + velocity.x);
//Sends out the ray at its respective spot an length

RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength, Color.red);

//If the ray hits, make velocity = distance to the hit distance - skin width
//Also reset the rayLength for edge height discrepencies
if (hit)
{
    //Reports the very first hit.distance and velocity.y at the first hit
    if (!temp && hit.distance != 0)
    {
        Debug.Log(hit.distance);
        Debug.Log(velocity.y);
        temp = true;
    }

    velocity.y = (hit.distance - skinWidth) * directionY;
    rayLength = hit.distance;
}

My problem is that when i run this simulation over and over, about half the time when the block collides with the flat surface it produces this initial "stopping force" a bit above the surface, and then the gravity on the block restarts and pulls it directly onto the surface.

So basically, sometimes it is sensing a collision at higher distances than other times forcing it to stop mid-air too early. I have mapped this out by watching the Debug.Log on the hit.distance and velocity.y. The times where this unfavorable effect happens, the hit.distance is above 0.1 and the velocity.y is about -9.56, while the times that are favorable the hit.distance is somewhere below 0.1 and the velocity.y is -9.67.

What is causing this difference in the simulation heights and numbers when i am not changing the system at all? Is it lag in the editor or something that needs to be accounted for? Will it show up on a mobile App?

Thanks for your help.


Solution

  • As comments confirmed, my suspicion was true:

    You are running this code in Update() not FixedUpdate() and therefore it isn't synchronized with the physics engine. The discrepancy (at a sub-update interval) caused the Update loop's code to execute early, imparting too much force, so by the time the physics simulation ran (on FixedUpdate's schedule) the object was still too high and gravity took over once more.

    The only solution is to move your code to FixedUpdate()