I'm making a game for the iPhone and I was wondering exactly how expensive ray casting is??? The main character in the game has the ability to scale during runtime and before they do I check around the player to make sure they're not going to scale through anything! Well my issue is I've done a lot of research on how to check left/right/up/down and see if it's clear and then stop the character from scaling or scoot them over, the whole nine yards... But the only thing that seems to work correctly is ray casting. So, I'm going to cast a bunch of rays each direction to make sure the player isn't going to blaze through some small object because they've scaled themselves way up. But I don't want to over do it if ray casting is super expensive. Thanks ahead of time for your help and any alternatives you can suggest to me would be greatly appreciated.
Things I've tried:
Trigger colliders on my objects and when the player hits that collider tell me what side it's on but when I get above a certain scale the trigger collider no longer detects the collision that's happening(even though I can physically see the character controller overlapping the trigger)
Line cast a box around my character... I'm not quite sure why this didn't work but it didn't.
Check sphere but you can't pass it a RaycastHit! So, I can't manually check to see where the object I'm colliding with is at in relation to my character.
Capsule cast... I was hoping to do this but I couldn't find any examples and the way it works is weird or I just can't wrap my head around why I can't just give the capsule an origin and then tell it how tall and wide it is. If anybody could give me an example of this....I would probably fall in love with you XD jk.
Sphere cast would've worked but to make the radius big enough to cover the width of my character it made the height to tall...
Check capsule...once again you can't tell where the object is that hit you...only that something is in the area.
3 Answers
3
How do you define expensive? The cost of a raycast is the cost of the intersection algorithm for each object checked until a hit is registered if the objects are depth sorted, otherwise, it must check every object. Simple object's have much simpler intersection algorithms. Raycasts that are far enough away from an object being checked should not check against the object, but should quit out early. Raycasts against convex 3D geometry even with a fast optimized algorithm is the cost of several subtractions, additions and in many cases at most like one division per triangle. The number of cycles taken by each of these operations is generally hardware dependent. If your scene has your colliders spaced enough, you are using simple colliders and you are not raycasting too often, it should be quite cheap.
These are some approaches to consider (some of which you have tried):
- If you know how big you are getting, you can limit the distance of your rays accordingly.
- Have you considered Physics.OverlapSphere? It returns the colliders that were overlapping. You can then check through the results of the overlap test to see where the colliders are in relation to your object, either by checking their positions or raycasting against them explicitly.
- Or you could try Physics.SphereCast which is about as expensive as OverlapSphere + a raycast and takes a RaycastHit. or Physics.SphereCastAll which returns all of the RaycastHits and is about the same as Physics.RaycastAll with your sphere's radius. These also include stuff for sweeping your sphere in space, but you probably don't need this.
- Or you could try Physics.CapsuleCast or Physics.CapsuleCastAll. The docs provide all the example you need and description of the input params. Point1 and Point2 are the ends (top and bottom) of your capsule, radius is the radius of your capsule, direction and distance are used for sweeping the capsule in space (which you probably don't care about) and the layerMask is a LayerMask. These can also give you RaycastHits.
I think the simplest/most aesthetically approach would be to add a ‘scale check’ game object with a collider the size of the max scale.
Enable that game object when you start to scale and use its collider impact to trigger force to try to ‘pop’ the character out of the area that is too small.
If there is no collider impact there, you are safe. If there is, you have a specific body you can ray cast against – or cone cast into the direction you are attempting to slide into as you scale (which you get from the impact point vs character point). Repeat over a few frames and you can get a smooth motion. If there is nowhere to ‘slide’ to, your head is going to hit the ceiling and explode.
What about making a mix of the two? You use the trigger and the second a trigger is detected you enter in RayCast mode and auto-disable raycast mode if raycast detect nothing in 10 seconds as an example.
Thanks for your reply! I'm glad to know that raycasting isn't very performance expensive! Right after I posted this I went in and made ray casts in 16ths along the side of my guy and it solved my issue and doesn't seem to bog down my system....however I still have to test this on the iPhone. If that doesn't work...your solution should work perfectly. Thanks again.
– anon29676987@Jeston: Agreed. The use of layermasks was the answer that I gave Dr. Watson in a previous question related to this topic. I would consider that part of "the proper environment," but it is worth mentioning.
– anon16733337Yea the rendered parts of my prefabs are the only parts, in all of my prefabs, that aren't ingnoring raycasts.
– anon29676987@skovacs1: To keep the capsule cast from sweeping would I use Vector3.Zero? That's what was confusing me from the start with that because I dont need to sweep.
– anon29676987