I continued to think about the object carry system, and decided to overhaul it one more time. I’ve actually lost count of how many times I’ve done this, but I think this time I’ve actually done it.
The last system I was using was the Spring Raycast System, which uses the spring method when the player was on the ground, and used the raycast system when the player was in free fall. More about that in this post.
However, there was still the problem when using the spring system, of the box you’re carrying penetrating other objects. In the last post, I posted on collision is very different depending on whether the rigidbody is kinematic or not, and so I had to have a system which made all non-moving boxes kinematic so that the box you’re carrying doesn’t get pushed into it.
But even with having the rigidbody set to kinematic, it wasn’t always 100%. It’s incredibly difficult when relying on this, because even if it happens 1 out 1000 times, that’s still a problem. And because it’s a bug that does happen occasionally, but is difficult to replicate, it’s pretty hard to debug.
I decided to be safe and just create a fool proof system.
Spring-Raycast Raycast System
I’m going it the Spring-Raycast Raycast System, because now, the spring system actually incorporates raycasts as well. Like the Spring Raycast system, we use Spring-Raycast while the player is grounded, and Raycast when the player is in free fall.
How does the Spring-Raycast system work?
We still use the spring to control the movement of the box, and when the box isn’t in contact anything, it’s just at the end of the spring.
However, on the box, we’re also sending out a series of raycasts from each face. On each face, we shoot out a raycast from the center, and if that doesn’t hit anything, we shoot out raycasts from the corner.
The raycasts are very short. They are 0.6 in length. Given that the box is 1x1x1, this means each ray protrudes out of the box by 0.1 only.
As soon as the box comes close enough to an object such that the raycasts detect it, then we position the box based on the distance to hit. This allows the box to be straight up aligned with the object. There is a slight magnetic effect at close enough range, which I think is actually bonus.
Anyway, this basically takes the best part of the raycast system, and doesn’t have the problems I mentioned in this post, such as the carried box being positioned in small spaces and getting drawn on top of meshes.
We’ve taken the overall movement of using actual collision, and added the precision accuracy of raycasts. Best of both worlds!
This is what it looked like before with just the Spring Raycast system. The yellow box is kinematic, while the green box is not:
With the new Spring-Raycast Raycast system, it doesn’t matter whether the box is kinematic or not:
Box Raycast System
There was also the problem of boxes occasionally falling through things. A very mild case is something like this:
I thought by implementing grid snapping this would fix the problem.
In the above case, this would probably work, and the grid snapping would cause the box to align to wall. However, grid snapping doesn’t fix the problem if the box penetrate deeply enough, which is really the root of the problem.
If the box penetrates pretty far into what’s below it, grid snapping doesn’t fix it, like here:
Sometimes, even when grid snapping did correct the position of the box, there was one frame in which the box penetrated before being snapped back, and even though it wasn’t noticeable, if you knew it was there, you’d see it all the time, and it was visually quite jarring.
There was also the issue where occasionally the box wouldn’t detect that what’s below has moved, and would end up floating in mid-air.
Since raycasts worked really well for carrying the box, I decided to implement it in the boxes as well.
Whenever the box is in free fall, I send raycasts downward. Like the system for object carrying, it sends one ray downward from the center, if that doesn’t hit anything, then we send rays downward from the corners.
If any of those rays hit something, we align the box based on distance to the hit point.
And if the box is stationary, meaning that there is something beneath the box, it’ll also conduct a series of tests with the rays. But as soon as any of the rays detect something, it’ll break out of the test. We only need one true positive to confirm that it’s working correctly.
If none of the rays detect anything, that means nothing is below the box, and so it needs to fall.
Here’s a gif showing the new boxes in action: