Search Unity

Is there a way to optimize RaycastHit?

Discussion in 'Editor & General Support' started by pastaluego, Apr 20, 2019.

  1. pastaluego

    pastaluego

    Joined:
    Mar 30, 2017
    Posts:
    196
    I noticed in the profiler the first time you access the hit.transform, it gets the transform, the collider, and the rigidbody (if it exists) as well even if you didn't try to access them. And then if on the next line I try to access the transform again it doesn't seem to have cached the first set of accesses and gets all 3 again.

    Am I misreading the profiler? How exactly does accessing a raycasthit work? Also why is it more performant if the object has a rigidbody even if it's static? Or is that perf difference specifically editor-only due to it trying to get a nonexistent component (if it doesn't have an rb)?

    Regardless, however it internally gets those components seems to cost more resources than the raycast itself, so I was just wondering if there was a way to isolate the parts of the raycasthit that I actually need without it having to get a bunch of stuff I don't. My game is very raycast heavy and I'm looking for any way to squeak out more performance.
     
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    Did you profile in the editor or a build?

     
  3. pastaluego

    pastaluego

    Joined:
    Mar 30, 2017
    Posts:
    196
    I did profile the build but it's difficult to know anything when only deep profile shows the accesses. However the relative performance difference when toggling on and off the raycasthit accesses match in both the editor and build, so I made the assumption it's still doing what I originally posted. Though I am curious if anyone knows specifically what's going on.

    For further evidence I tested caching the transform to a custom struct that contains a Transform instead of accessing the RaycastHit for a second time. The results showed that accessing the transform directly from the RaycastHit twice was twice as slow as accessing it once and then accessing the custom struct with the cached transform.
    Code (CSharp):
    1.  
    2. public struct TransformCacheStruct {
    3.     public Transform transform;
    4. }
    5.  
    6. TransformCacheStruct cache = new TransformCacheStruct();
    7.  
    8. for(int i = 0; i < ray_iterations; i++) {
    9.     int count = Physics2D.Raycast(Vector2.zero, Vector2.right, filter, results, 5);
    10.  
    11.     if (count > 0) {
    12.         if(cached_hit) {
    13.             if (access_hit) {
    14.                 Transform t = results[0].transform;
    15.                 cache.transform = t;
    16.                 if(access_hit_again) {
    17.                     Transform t2 = cache.transform;
    18.                 }
    19.             }
    20.         } else {
    21.            if (access_hit) {
    22.               Transform t = results[0].transform;
    23.  
    24.               if (access_hit_again) {
    25.                  Transform t2 = results[0].transform;
    26.               }
    27.            }
    28.        }
    29.          
    30.    }
    31. }
    32.  
    I could be doing something wrong, so if anyone can explain what exactly accessing a raycasthit is doing internally I'd be grateful. I also apologize for my variable naming convention.
     
    Last edited: Apr 20, 2019
  4. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
  5. pastaluego

    pastaluego

    Joined:
    Mar 30, 2017
    Posts:
    196
    Ok thanks I couldn't find it. So I'm right. Is there no way to improve this on Unity's end?
    Code (CSharp):
    1. public Transform transform
    2.         {
    3.             get
    4.             {
    5.                 Rigidbody2D body = rigidbody;
    6.                 if (body != null)
    7.                     return body.transform;
    8.                 else if (collider != null)
    9.                     return collider.transform;
    10.                 else
    11.                     return null;
    12.             }
    13.         }
    I use a lot of raycasts and my transforms don't have rigidbodies. Yet every time I want to just access the transform, it internally gets the collider and rigidbody, (both of which do
    Code (CSharp):
    1. Object.FindObjectFromInstanceID(m_Collider) as Collider2D;
    even though I don't need them and adds a lot of overhead. And it doesn't cache them internally on top of that.

    Besides caching the first access on my end, is there anything I can do to improve RaycastHit access performance? Besides making sure every single gameobject with a collider has a rigidbody, even static ones, which seems kind of ridiculous to me.
     
    Last edited: Apr 21, 2019