Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Buggy Physics.Raycast fails for moving objects?

Discussion in 'Editor & General Support' started by Wolfram, Aug 12, 2010.

  1. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    263
    Hiho.

    For our GUI we're using 3D-objects (since the GUI stuff is not flexible enough for us), that are attached to the Camera. However, when the camera is moving (and therefore, the button, as a child of the camera, is moving along with it), Physics.Raycast no longer hits the button reliably (or at all), and seems to refer to object positions of (at least) the previous frame.

    So although the Button is a direct child of the Camera, and the Physics.Raycast is fed the frame-current position of that camera, it fails to see the button at its current position - it appears the collider used to do the intersect testing still refers to an outdated position of that child.

    When doing the camera movement in Update() and the Raycast in the button script also in Update(), the results are pretty weird. This might be understandable, since it is undefined which Update() function is processed first.

    However, even when doing the Raycast in LateUpdate(), it *still* doesn't work, as you can reproduce by yourself:

    In the testcase, there is a button attached to a camera, and a cube somewhere farther away. A script attached to camera and cube will translate them along -X, so when pressing Play you won't see anything move except the point light:
    - the cube appears stationary because it moves at the same speed as the camera
    - the button appears stationary because it is attached to the camera
    - the plane appears stationary because it is of constant color and very large (it actually *is* stationary, but not relative to the camera)
    The Raycasting script in LateUpdate() is attached to the Cube and the Button. They both test the whole scene.

    If you now click at A, both Raycasts correctly give "Button" as a result.
    Clicking at B will give "Button" most of the time, but in about 1/10 cases, both will return "Cube"! (without moving the mouse!)
    Clicking around C (a few pixels to the left/right make a huge difference here), will either always return the Plane (although both Cube and Button are in front), a few pixels to the right both will return Plane and Button 50/50, and a few pixels more to the right both will return Button and sometimes Plane - never Cube.
    Finally, clicking around D will always return Plane, never Button.

    Is this a known bug?
    Is there a workaround? Because at the moment, we cannot interact with our GUI as long as the camera is animated/in motion (which of course happens frequently) :-/
    BTW, Unity 3b5 has the same bug.
    (for reference this is Windoze Vista, Pro version, and I get framerates of about 200fps)

    Thank you for any help on this.

    EDIT: Maybe the *real* question is, when are the data structures used for Physics.Raycast updated? Or is there a command to force an update? Is Physics.Raycast only allowed in FixedUpdate? (which would be bad, since objects can be moved around all the time)
    For example, we had some real trouble when we tried to adapt some of the uniTUIO scripts to our needs - we noticed the Unity Editor will simply crash when Physics.Raycast is called outside the Update() functions (i.e., whenever an asynchronous TUIO touch event was received). Is the answer to that "Yes, that is to be expected", or is it "Oops, that shouldn't happen"?

    EDIT2: Oh, I just realized the testcase I attached was for Unity3, and the scenes apparently are not backwards compatible. So I also attached a 2.6 testcase, which also extends the original testcase by a cube with a Unity animation. Switch between ScriptedAnim_Update, ScriptedAnim_FixedUpdate, and the Animation with "AnimatedPhysics" on/off for both cubes and the camera, for the different behaviours. Note: everytime you see a jerky cube, that's to be expected, since either *all* objects need to use FixedUpdate, or *all* need to use Update.
     

    Attached Files:

  2. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    263
    So, shall I open a bug for this?
     
  3. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Just a thought... have you tried doing the raycast in Update and then moving the camera in LateUpdate?
     
    C_R_M likes this.
  4. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    263
    I tried all permutations of Update() and LateUpdate(), no luck.

    I also opened this as a question on UnityAnswers ( http://answers.unity3d.com/questions/25773/ ), and while doing that I noticed that it does work correctly when I do *all* object and camera manipulations in FixedUpdate(). A Physics.Raycast anywhere (FixedUpdate/Update/LateUpdate) will then always give the correct result.

    But checking and modifying all of our 250 scripts, moveing any transformations to FixedUpdate, plus fixing all UnityAnimations to also sync with the physics update is something I'd really like to avoid :-/
     
    Last edited: Feb 16, 2015
  5. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    263
    UPDATE:

    Hm, I "sort-of-fixed" the problem by modifying our scripts to use FixedUpdate instead of Update (luckily, only a fraction of the 250 scripts are concerned with camera motion or are relevant to Physics.Raycast calls), by making sure that AniMate uses FixedUpdate as well (by setting the "physics=true" property), and by also enabling "AnimatedPhysics" for all relevant external or Unity Animation nodes.

    However, I still consider this a bug, since you WILL, per definition, get jerky motion if you animate your camera+objects in FixedUpdate instead of Update (especially if your framerate is similar to the physics update rate), since the transformations are no longer in sync with the rendered frames. Also, if the answer to the problem is "yes, that's to be expected, the Physics engine relies on FixedUpdate", I would expect at least a BIG warning notice in the documentation that you cannot use Physics.Raycast for objects animated outside of FixedUpdate().

    I'm now off to testing our whole project (28 Scenes with 1.3GB data) for side-effects or jerky animations... :-/

    Submitted as bug #372042.
     
    AmalLama likes this.
  6. mohydineName

    mohydineName

    Joined:
    Aug 30, 2009
    Posts:
    301
    Wolfram,

    Has this been fixed in Unity 3.1?
     
  7. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    263
    No, the behaviour hasn't changed. Using Unity 3.3.0f4 Windows.
     
  8. benni05

    benni05

    Joined:
    Mar 17, 2011
    Posts:
    62
    Confimed, hit the same probleme here now. Will try whether the workarounds mentioned here do work for me as well.

    Ben
     
  9. spectre1989

    spectre1989

    Joined:
    Oct 6, 2009
    Posts:
    125
    I'm also fighting with this, but what I'm trying to do is to raycast against an object, move it, raycast again, move it again, all in the same FixedUpdate. Putting all object manipulation in FixedUpdate doesn't fix this, as I can show from this very simple test case:

    As you can see a potential workaround is to explicitly call Raycast on individual Colliders, far from satisfactory as I'm sure you'll agree.
     
  10. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,598
    I'm not even using animation and still hitting this problem. Using FixedUpdate doesn't help either

    Code (csharp):
    1.  
    2.       if (evt.phase == TouchPhase.Stationary)
    3.       {
    4.          var ray : Ray = Camera.main.ScreenPointToRay (evt.position);
    5.          var hits : RaycastHit[];
    6.          hits = Physics.RaycastAll (ray, 20);
    7.          if (hits.length > 0) {
    8.             displayLabel = structAccess.GetNameFromModelName(hits[0].transform.gameObject.name);
    9.          }
    10.       }
     
  11. CapnCromulent

    CapnCromulent

    Joined:
    Sep 7, 2010
    Posts:
    45
    I'm having a similar problem trying to raycast against moving objects, but Wolfram, I think you can solve your immediate problem by using two cameras.

    1) Put all your interactive elements on a UI layer
    2) Set your main, animating camera to render everything except the UI layer
    3) Create a 2nd stationary camera that only renders the UI and set the depth to be greater than that of your main camera.
     
  12. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    263
    An interesting idea, thanks!
    I'll keep that in mind.
     
  13. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You can't move-test-move-test because the physics engine has to run, and it will only run each fixedupdate cycle once.
     
  14. radiolobito

    radiolobito

    Joined:
    Jun 12, 2009
    Posts:
    117
    i'm in unity 3.4.2 and have the same trouble... i have a raycast attached at a moving car... i want to the raycast detects another cars (moving too) but i have no results... any idea?
     
  15. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    use more simultaneous raycasts instead of testing the same one.
     
  16. radiolobito

    radiolobito

    Joined:
    Jun 12, 2009
    Posts:
    117
    each car have one raycast, to detect another in front... my problem is that the raycast detects all objects without movement... but not the cars moving
     
  17. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    263
    Have you tried doing all object movements in FixedUpdate(), not in Update?/LateUpdate()? What do you use to move your cars? Direct modification of the transform, animations, rigidbody forces, CharacterController, ...?
     
  18. radiolobito

    radiolobito

    Joined:
    Jun 12, 2009
    Posts:
    117
    i'm movin with direct transform.Translate, no animation, no rigidbody, no character controller; all the cars with mesh collider. the movement is on FixedUpdate and the raycast is in Update(); i tried animation and raycast both in Update() and happens the same
     
  19. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    577
    Sounds like this is the same issue as fast projectiles going through colliders. The bullets travel so fast that the go right through the collider from one time step to the next. Same issue here? If so, not a bug, just time step reality.
     
  20. radiolobito

    radiolobito

    Joined:
    Jun 12, 2009
    Posts:
    117
    the velocity of the cars is about 5 * Time.deltaTime
     
  21. MarcusD

    MarcusD

    Joined:
    Mar 25, 2011
    Posts:
    7
    Hi,

    I am having the same kind of troubles (i.e. rays do not hit moving objects with a mere collider), there is a post on Answers with a small demo which demonstrates this problem. I noticed that as soon as you add a rigidbody to your target object the raycast hits (I tried this after having read "If you are moving a GameObject through its Transform component but you want to receive Collision/Trigger messages, you must attach a Rigidbody to the object that is moving." in the reference).

    Marcus
     
    Last edited: Nov 24, 2011
    Ermiq likes this.
  22. nshack31

    nshack31

    Joined:
    Nov 4, 2011
    Posts:
    96
    3.5.2 now and its still a problem :(
     
  23. tasadar

    tasadar

    Joined:
    Nov 23, 2010
    Posts:
    291
    it seems like it is.
    i have also bumped into this today. my projectiles hit stationary units but sometimes cant hit the ones that are moving towards me.
    units have a trigger collider and kinematic rigid body.
     
  24. Sparticus

    Sparticus

    Joined:
    Mar 15, 2014
    Posts:
    149
    Sigh, is this really still a bug? Using the latest version of unity and this is happening to me :(

    Is there a workaround without having to put my camera movement in fixedUpdate? I don't want jerky camera movement
     
  25. shaanbhaya

    shaanbhaya

    Joined:
    Jul 4, 2012
    Posts:
    6
    Well i think i have solved this to some extent .What i did was
    • In Edit->projectsetting ->time->Fixed-Timestep ,put the time to be 0.01
    • Put my camera in LateUpdate(),as anything else is giving jerky movement.
    • Put my movement and physics in Late Update as well.
    • Put my platform Movement script in FixedUpdate(),and then making a function like this and then calling it after fixed update using "Yield".
      Code (JavaScript):
      1. function PlatMove()
      2. {
      3.  
      4. if(TimeBased)
      5. {
      6.    t+=Time.deltaTime;
      7.    if(t>time)
      8.    {
      9.      Switch=BooleanChange(Switch);
      10.      t=0;
      11.    }
      12. }
      13. else
      14. {
      15. if(transform.position == DestinationSpot.position)
      16.     {
      17.         Switch = true;
      18.     }
      19.     if(transform.position == OriginSpot)
      20.     {
      21.         Switch = false;
      22.     }
      23. }
      24.    
      25.    
      26.     if(Switch)
      27.     {
      28.        
      29.       yield WaitForFixedUpdate();
      30.       if(TimeBased)
      31.       transform.Translate(Vector2(0,-Speed*Time.deltaTime));
      32.       else
      33.       transform.position = Vector3.MoveTowards(transform.position, OriginSpot, Speed*Time.deltaTime);
      34.     }
      35.     else
      36.     {
      37.        
      38.     yield WaitForFixedUpdate();
      39.     if(TimeBased)
      40.     transform.Translate(Vector2(0,Speed*Time.deltaTime));
      41.     else
      42.     transform.position = Vector3.MoveTowards(transform.position, DestinationSpot.position, Speed*Time.deltaTime);
      43.     }
      44. }
      45. static function BooleanChange(bool:boolean):boolean
      46. {
      47. if(bool)
      48. return false;
      49. else
      50. return true;
      51. }
    This has resulted into a consistent collision detection till my speed is not over 12,and since mine is a platform i dont need more than 10.If you try the speed to more than >12,its the same unreliable collision .
     
  26. davidjohn123

    davidjohn123

    Joined:
    Jan 8, 2016
    Posts:
    3