How do I do a spherecast/boxcast/whatever but have the radius increase proportionally with distance?
I'm working on a mod for a VR game called Anyland, which is based on Unity 2018. I'm trying to code a feature that lets you move distant objects using perspective trickery. For instance, you could hold your hand in front of a mountain in the distance, and grab it as if it was a tiny mountain right in front of you, and it'll actually appear in your hand at that small size. Then you can put it down, and it will (optionally) become large and distant again.
Here's a video of what I have so far: https://www.youtube.com/watch?v=3vGAd-QgOog
The thing is, I'd like it to look the same after you put it down, both to complete the effect as well as because it might be useful. (Since this is VR, the assumption is the player will close one eye to eliminate depth perception and see from a single point.) But these objects can be any shape. Currently, what I have just does a basic raycast from the object's center point, but this is inadequate, as the geometry around the center point can still intersect with things.
What would be near-perfect would be a collider-cast, that sweeps the shape of the object's collider toward a point, but I'd be willing to settle for a boxcast of its bounding box, or a spherecast. The problem is, as the object gets farther away, it'll need to be proportionally larger, to keep it the same size visually. Which means the radius that's checked for collisions needs to increase over distance. But the geometry-cast functions all seem to have only a single (set of) size parameter(s), not a "start size" and "end size". (Not that a ray has an end—the idea is I'd specify a size at two different points and it would linearly interpolate.)
Does anyone know how I should approach this problem?
I found this, which looks like it will work for my purposes. https://github.com/walterellisfun/ConeCast If anyone knows an even better solution though, please do share!
Answer by lgarczyn · Nov 21, 2019 at 04:07 AM
I would suggest a series of SweepTest, each doing a small part of the trajectory, reducing in scale exponentially.
However, since SweepTest needs to have a rigidbody attached, I'm not even sure that the scale would update in time for it to work, though it should. It would also require you to move your rigidbody, and possibly mess with other scripts. Also it would only work with convex meshes. Unity to my knowledge doesn't provide a real ConvexMeshCast function.
You can avoid moving the rigidbody if you just scale it down, and do a SweepTest from the same place, but with a higher max distance.
Another way would be to load the mesh in memory, and iterate on every point. apply the object's transform to them, and finally launch a raycast to every point, or at least the ones further out. Again, pretty expensive, but not too much. You can also use RayCastCommand to do a lot of raycasts for quite cheap. You can also use SphereCasts to make sure there are no "holes" in the area you are checking.
Another way would be quite complicated to do, but could work. Basically you could use a second camera with stencils, and detect whenever another polygon is drawn over your target object. If one is drawn, output a certain color. Then check the render texture for that color. Again, expensive, not pretty, and completely overkill. But theoretically possible.
Your answer
Follow this Question
Related Questions
Raycast collisions being detected along a non-existent curve(?) 1 Answer
How do Contact Filters work? 1 Answer
Raycast ignores objects with colliders 1 Answer
SphereCastAll hit.point are allways zero 1 Answer
raycast or collision? 1 Answer