- Home /
Help with Physics.BoxCast (or maybe ray casts in general?)
I've been struggling with this issue for days. Please, someone help.
I've got a sphere whose movement I need to restrict when rolling up steep slopes. I've been able to make this work, sorta, but the last bit of fine-tuning is giving me trouble. Can anyone help?
I'm currently using a standard Physics.Raycast to check for when I'm on a steep slope. The follow code is attached to the sphere I need to restrict:
public class BallEntity : MonoBehaviour
{
//slope movement https://www.youtube.com/watch?v=GI5LAbP5slE
[Header("Slope Control")]
[SerializeField] float _groundRayDistance;
[SerializeField] private RaycastHit _slopeHit;
[SerializeField] float _slopeLimit;
public bool OnSteepSlope()
{
if (CheckIsGrounded() == false) return false;
float scRadius = GetComponent<SphereCollider>().radius;
if (Physics.Raycast(gameObject.transform.position, Vector3.down, out _slopeHit, scRadius + _groundRayDistance))
{
float _slopeAngle = Vector3.Angle(_slopeHit.normal, Vector3.up);
if (_slopeAngle > _slopeLimit)
{
return true;
}
}
return false;
}
}
This works (well enough), but as expected, given the shape of the sphere and the position of the raycast (center of the sphere), my method allows the sphere to move up the slope a bit before the steep slope is detected. See the image below, which uses OnDrawGizmos() to show the position of the raycast in red:
I tried:
Using Vector3.forward along with the sphere's radius to place the origin of the RayCast at the front of the sphere. I got close with this method, but I couldn't get it to work.
Using a SphereCast instead of a standard RayCast. I couldn't get this to work.
Using a BoxCast instead of a standard RayCast. I couldn't get this to work either.
Is one of the three methods above the best way to solve this issue? If so, I suppose I might be doing something wrong. Or, is there a simpler method that I haven't considered?
Thank you so much for all your help!
Answer by Captain_Pineapple · Mar 01 at 07:47 PM
Hey there,
If you have issues with Box/Spherecasts then please share your approach so that we may see what you tried. A spherecast may indeed solve this issue but i'd like to offer another approach:
Try using the OnCollision callbacks. They give you a Collision
as argument. If you get a collision you can check the current contact point for its normal.
if(Vector3.Angle(collision.GetContact(0).normal, Vector3.up) > 60)
// we are on a steep slope.
This will need some fiddling around as well to get it to run but should solve your issues and give consistent results. Only thing you have to watch out for: if you are in collision with multiple objects at once things can get confusing.
Your answer
Follow this Question
Related Questions
How to get distances of GameObjects through SphereCast? 1 Answer
SphereCastAll doesn't seem to be working 2 Answers
SphereCast Arguments 1 Answer