Search Unity

Problem with RayCast ¿Lag or bug on start?

Discussion in 'Editor & General Support' started by pleasurehouse, Mar 12, 2021.

  1. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96
    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!!
     

    Attached Files:

  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    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.
     
  3. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96
    -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.


    Code (CSharp):
    1.  
    2.  
    3.  /// -------------------------------------------------------------------------------------
    4.     public bool IsHitting(Vector2 origin)
    5.     {      
    6.  
    7.         hit = Physics2D.Raycast(origin, this.direction,  this.distance, layerMask);
    8.  
    9.         rc_green = new RaycastDrawer(this.direction, Color.green, this.distance);
    10.         rc_red = new RaycastDrawer(this.direction, Color.red, this.distance);
    11.  
    12.      
    13.         if (hit)
    14.         {
    15.             rc_red.Draw(origin);        
    16.             return true;
    17.         }
    18.         rc_green.Draw(origin);      
    19.         return false;    
    20.     }
    21.  
    22. /// -------------------------------------------------------------------------------------
    23. public class CanyonMainController : MonoBehaviour
    24. {
    25.  
    26.     RaycastHandler rc;
    27.  
    28.     void Start()
    29.     {
    30.      
    31.         rc = new RaycastHandler(Vector2.up, 3f);      
    32.      
    33.     }
    34.  
    35.     void Update()
    36.     {    
    37.    
    38.         rc.direction = Vector2.up;
    39.         rc.distance = 2f;
    40.         Vector2 origin = transform.position;
    41.         rc.IsHitting(origin);
    42.   }
    43. }
    44. /// -------------------------------------------------------------------------------------
    45.  
    Thank you for your response and your help!!
     
  4. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    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.
     
    Last edited: Mar 13, 2021
  5. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96

    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!!
     
  6. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96
    The build works perfect... i'm 99% sure.. the problem is the hold on windows

     
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    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.
     
  8. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96

    I think i doing like you said


    Code (CSharp):
    1.  
    2.  
    3.  //-------------------------------------------------
    4.     private void MoveX()
    5.     {
    6.         if (isWall)
    7.         {
    8.             speedX = -speedX;
    9.             transform.localScale = new Vector3(-1f * transform.localScale.x, transform.localScale.y, transform.localScale.z);
    10.             transform.position = new Vector3(transform.position.x , transform.position.y,  transform.position.z);
    11.         }
    12.         else
    13.         {
    14.  
    15.             transform.position = new Vector3(transform.position.x + (speedX * Time.deltaTime),
    16.                                                 transform.position.y,
    17.                                                 transform.position.z);
    18.         }
    19.     }
    20.     //-------------------------------------------------
    21.     void FixedUpdate()
    22.     {
    23.              rc.direction = Vector2.right;
    24.              rc.distance = 2f;
    25.              isWall = rc.IsHitting(transform.position);      
    26.     }
    27.     //-------------------------------------------------
    28.     void Update()
    29.     {
    30.          if(!stop)MoveX();
    31.     }
    32.  
    33.  

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

    Code (CSharp):
    1.  
    2.     void Update()
    3.     {
    4.           rc.direction = Vector2.right;
    5.           rc.distance = 2f;
    6.           isWall = rc.IsHitting(transform.position);
    7.  
    8.          if(!stop)MoveX();
    9.     }
    10.  
    How would you do it?
     
    Last edited: Mar 14, 2021
  9. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    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:
    Code (CSharp):
    1. Vector3 direction = *initialdirection*;
    2.  
    3. // Do the raycast on direction
    4. // Switch it left / right when hit with "direction = -direction;"
    5.  
    6. // Then to add movement delta, just do:
    7. 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)
     
    pleasurehouse likes this.
  10. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    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.
     
    pleasurehouse likes this.
  11. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96

    I going to try it... OMG!! I have to change four month of codes.. :-(
    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!!
     
  12. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96


    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...




    Code (CSharp):
    1.    
    2.  
    3. direction = Vector2.right;
    4.  
    5.  //-------------------------------------------------
    6.     private void Move()
    7.     {
    8.         rc.distance = 50f * Time.deltaTime;      
    9.         isWall = rc.IsHitting(transform.position);
    10.  
    11.         if (isWall)
    12.         {
    13.             rc.direction = -rc.direction;
    14.             transform.Rotate(transform.rotation.x, transform.rotation.y + 180f, transform.rotation.z, Space.Self);
    15.         }
    16.         else
    17.         {
    18.             transform.position += speedX * (Time.deltaTime) * direction;
    19.         }
    20.     }
    21.     //-------------------------------------------------
    22.     void FixedUpdate()
    23.     {
    24.         Move(); //--> it works  
    25.     }
    26.     //-------------------------------------------------
    27.     void Update()
    28.     {
    29.         Move();//--> it doest'n works
    30.     }
    31.  
    32.  

    Thank you so much xVergilx!!!! You saved my game!! :)
     
    xVergilx likes this.
  13. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    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:
    Code (CSharp):
    1. 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 :)
     
    pleasurehouse likes this.
  14. pleasurehouse

    pleasurehouse

    Joined:
    Oct 15, 2020
    Posts:
    96

    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. :) cheers!!
     
    xVergilx likes this.