Combining RayCasts or working with 2D sprites

I am currently having a performance issue due to code. I do a lot of RayCast in the project and it slow the application down.

For instance I activate those RayCasts only when the user touches screen and I can observe the framerate going from 20 to about 14 on my iPodTouch (1st gen) when the Raycasts are activated. Which is a problem.

Here is the problem, simplified : trying to detect if a segment “on screen” (2D) is intersecting a sphere. First thing I did was test points with raycast let say every 10 pixels on the segment. This is what slows the app down. I understand raycasting with ANY object is complex to do and thus costly in terms of perf, but I only do it with spheres (or could use disks if i was in 2D) and multiple times with the SAME sphere.

So I guess there may be many improvements to this but I’m not sure which way to go :

  1. Is there a way to transform a 3D object in some sort of 2D Shape and then do the test faster in 2D (since i do multiple point tests with the same object) ?
  2. Should I recover somehow the center of the sphere, get (how?) the radius of the disk (which isnt exaclty a disk due to perspective) corresponding “on screen” then work from here (should be VERY fast if i can get center and radius right).
  3. Should I go for using the SpriteManager (http://forum.unity3d.com/viewtopic.php?t=17864) and work from there (hope it gives access to informations on “sprites”, like shapes data “on screen” i could use to detect hit).
  4. Or maybe there is a simple native way to combine multiple raycasts on one object to improve performance compared to doing n times a new raycast and checking the hit with same object.
  5. I don’t think its possible to directly test if a segment (and not a point) intersects an object, but who knows^^
  6. Any another idea ?

If someone has already had that kind of problem or can point me in what should be the best choice here, I’d appreciate it a lot.
Thanks!

Hard to know without seeing your code, but have you tried using a box collider instead of a mesh collider on your spheres? Also have you set the Layer Mask on your raycast call? Those two things should bump up the performance I guess.

Also rule out other things that could cause slow performance during touches (like OnGUI() objects)

I use a sphere collider (even if the object isnt a sphere mesh) but thats because what the gameplay should be, not boxes, no real choices here.

I dont use the layer mask since i use directly collider.raycast and not physics (which i think is best if you know which and only object u want to test the raycast with).

There are things onGUI (i show framerate + average on last 40 frames^^) but they are the same with or without touching, those have nothing to do with it.

But the strange thing i just observed it this :

  • even if i remove the call of my raycasts function, touching the screen already makes frames drop from 20 to 15 per sec (with no more object than before and no more onGUI stuff, or at least I think…). Am i hallucinating about this ? I dont think just touching screen without doing nothing affect performance that much, so maybe im just missing something in my code…

It sounds like you have optimized the raycast stuff pretty well.

I think your OnGUI() functions might be having more of an impact than you think. You can use XCode Instruments to see the actual framerate of your game, and not even have to mess with displaying on screen. Alternately you can display the framerate in a GUIText, which is much faster, instead of OnGUI.

Thanks.

So you mean that adding component (GUIText, GUILabels, etc) to the camera in IDE is faster than drawing these same inside the OnGUI() function of the camera ?

If so thanks a lot, I’ll switch all interface from here to there.

Yep there have been some threads discussing there where it’s recommended to update a GUIText and GUITexture which is very fast, and remove your OnGUI() functions completely. Just touching the screen with OnGUI can effect the framerate a lot.

If you must use OnGUI (like in the main menu or something where framerates dont matter) make sure to disable useGUILayout. The iphone docs say additionally:

I am not sure what “use GUI functions instead” is supposed to mean. But GUIText and GUITexture are probably what they meant.

It means to use GUI instead of GUILayout. But GUIText/GUITexture are faster still.

–Eric