Problem with RayCast ¿Lag or bug on start?

Problem with RayCast ¿Lag or bug on start?

I see my Raycast is failing in the first second of the execution. I was thinking it was my code problem, but while i was recording the video i saw the problem is the “hold on” window. (i have the mostly of my GameObject disableds).

The program start to executing before the “hold on window” is close and this cause the raycast not working during this time. And my dron do not detecting the walls. XD

So… there is some settings to solve this problem? ¿Or some way to do standby until hold on windows will be close?

Thank you so much!!

Print out what the raycast hit. Did the raycast even happen? Print its start and direction. Does that seem reasonable?

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.

-Print out what the raycast hit.–> hit nothing
-Did the raycast even happen → nope
-Print its start → it is transform.position of my gameObject
-Print direction- → Vector2.up

-To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Of course i did it

Doing this should help you answer these types of questions:

I nkow it,

- what are the values of the variables involved?

I’ll show you in the following code

-Are they initialized?

of course

I was testing it a lot… and even disable all my scripts and all my GameObjects… and even i reduced the code to minimum to test only the raycast function… my conclusion is Physics2D.Raycast() does not works while “hold on windows” is open… it is just a second, probably when executing the build that not happens… but that second was enough to my dron through the wall in developer mode. Thank to the video i realized it.

Anyway, this is my code… i think it is well done. I was using it for 4 month without problems. Until today that i see that issue.

 /// -------------------------------------------------------------------------------------
    public bool IsHitting(Vector2 origin)
    {       

        hit = Physics2D.Raycast(origin, this.direction,  this.distance, layerMask);

        rc_green = new RaycastDrawer(this.direction, Color.green, this.distance);
        rc_red = new RaycastDrawer(this.direction, Color.red, this.distance);

     
        if (hit)
        {
            rc_red.Draw(origin);         
            return true;
        }
        rc_green.Draw(origin);      
        return false;     
    }

/// -------------------------------------------------------------------------------------
public class CanyonMainController : MonoBehaviour
{

    RaycastHandler rc;

    void Start()
    {
      
        rc = new RaycastHandler(Vector2.up, 3f);      
      
    }

    void Update()
    {     
    
        rc.direction = Vector2.up;
        rc.distance = 2f;
        Vector2 origin = transform.position;
        rc.IsHitting(origin);
  }
}
/// -------------------------------------------------------------------------------------

Thank you for your response and your help!!

It could be caused by movement logic itself.

Since editor performs some operations in the background, as a result:

  • FPS drops, causing FixedUpdate to run multiple times per frame at fixed time which moves object;
  • Raycast in Update checks much more later, since its execution rate is based on frame rate.

If that’s the case - you’ll probably encounter same bug in build as well, once FPS drops.

Solution to this would be to check collision before movement, not randomly once per frame.
Order is always important when performing collision checks.

Yes, i do it like you said. But i think that is not the problem… if you watch the video in slow motion you can see what is happening very well.

-Steep 1. The “hold on” windows is open
-Steep 2. RayCast is Working
-Steep 3. Dron is moving
-Steep 4. RayCast is not Working even the raycast gizmos is not working too… all this while “hold on” windows says “GUIVew.RepaintAll…” → RepaintAll → very suspicuis
-Steep 5. “hold on” windows is close
-Steep 6. All works well again

i goin to try with the build to see what happen… i will tell you it!!

The build works perfect… i’m 99% sure… the problem is the hold on windows

https://www.youtube.com/watch?v=DXQi7_6gqIA

Build doesn’t have FPS issues. (judging from the video)

Just try testing collision before movement. It should fix your issue.
Its not that hard to just add a few lines.

I think i doing like you said

 //-------------------------------------------------
    private void MoveX()
    {
        if (isWall)
        {
            speedX = -speedX;
            transform.localScale = new Vector3(-1f * transform.localScale.x, transform.localScale.y, transform.localScale.z);
            transform.position = new Vector3(transform.position.x , transform.position.y,  transform.position.z);
        }
        else
        {

            transform.position = new Vector3(transform.position.x + (speedX * Time.deltaTime),
                                                transform.position.y,
                                                transform.position.z);
        }
    }
    //-------------------------------------------------
    void FixedUpdate()
    {
             rc.direction = Vector2.right; 
             rc.distance = 2f;
             isWall = rc.IsHitting(transform.position);       
    }
    //-------------------------------------------------
    void Update()
    {
         if(!stop)MoveX();
    }

i tried do it like this too but doesn’t work either

    void Update()
    {
          rc.direction = Vector2.right; 
          rc.distance = 2f;
          isWall = rc.IsHitting(transform.position);

         if(!stop)MoveX();
    }

How would you do it?

Raycast direction is incorrect;
Try inverting direction once wall is hit instead of speed itself.

(Since frame time can be ~0, and raycast direction not changing, it may cause undefined isWall state. Also, it doesn’t seems to change at all in your code snippet)

Also, you can add delta directly with direction * speed, e.g. like so:

Vector3 direction = *initialdirection*;

// Do the raycast on direction
// Switch it left / right when hit with "direction = -direction;"

// Then to add movement delta, just do:
transform.position += speed * deltaTime * direction;

Another unrelated tip - try to avoid negative scale, as it can cause visual glitches and break batching, reducing performance. (Rotate your sprite instead)

Missed one more thing - make sure your ray distance is multiplied by deltaTime (distance = “initialdistance” * deltaTime) when performing movement collision tests. Adjust values in editor accordingly.

Otherwise when framerate drops, deltaTime becomes just too large, and object will just clip through the wall. This is because movement step would be larger than actual raycast length. And it will not hit the wall.

I going to try it… OMG!! I have to change four month of codes… :frowning:
OK, when i finish it, i’ll show you how it works.
Thank you so much for you explained and for your time. Very Very appreciated!!

Yessss!! it works!! XD

But only if i put the code inside of FixedUpdate()… inside of Update() doest’n works… I had readen that in FixedUpdate() is not necessary to use “Time.deltaTime”, but i tried without it too and it don’t works so well…

direction = Vector2.right;

 //-------------------------------------------------
    private void Move()
    {
        rc.distance = 50f * Time.deltaTime;       
        isWall = rc.IsHitting(transform.position);

        if (isWall)
        {
            rc.direction = -rc.direction;
            transform.Rotate(transform.rotation.x, transform.rotation.y + 180f, transform.rotation.z, Space.Self);
        }
        else
        {
            transform.position += speedX * (Time.deltaTime) * direction;
        }
    }
    //-------------------------------------------------
    void FixedUpdate()
    {
        Move(); //--> it works  
    }
    //-------------------------------------------------
    void Update()
    {
        Move();//--> it doest'n works
    }

Thank you so much xVergilx!!! You saved my game!! :slight_smile:

Time.deltaTime in FixedUpdate is equal to set physics timestep in settings (Time.fixedDeltaTime), and doesn’t change based on framerate.
So if you set 0.02, it will always be 0.02;

In Update - deltaTime is based on the time passed since last frame. So it can be anything from 0 to inf.
But if your application runs in 60 fps it should be ~0.16f (ms);

There’s another way to setup distance, which may work in Update, something like this:

distance = speed * deltaTime + initialDistance;

This should compensate movement that is performed later on, and simplify setting up initial distance.
Alternatively, you could use something like 2f * deltaTime to ensure it always hits.

Anyway, glad to help :slight_smile:

Thank you so much xVergilx!!
Now i have to update a lot of scripts… i would wish to have known all this four month ago. :slight_smile: cheers!!