- Home /
How to get the center of a CapsuleCast or SphereCast on collision
I have a CapsuleCast being projected from my previous position to my current position in order to detect if I have collided with anything. If I have collided, I want to teleport the player to the CapsuleCast center from when it returned a hit.point.
Since the CapsuleCast will be the same size as my players capsule, and since my players pivot point is at the center, which is also the capsule colliders center on my player, if I can just get the center of the CapsuleCast from when it hit a collider, I can just teleport the player to the CapsuleCast center which will align my players capsule with the CapsuleCast. I can then offset it by a tiny bit to bump the character a bit more away from the collider it is colliding with.
The CapsuleCast hit.point could be anywhere when it hits a collider. It could be somewhere near the top of the CapsuleCast collider, or somewhere near the middle. I have no idea where the hit.point is relative to the CapsuleCast collider.
I can think of a possible different way to get the results I want, such as instead of a CapsuleCast I can maybe just use a gameobject with a capsule collider and imitate what the CapsuleCast is doing by moving the capsule collider from the players previous position to the players current position, and have a check for OnCollisionEnter and such, and now I'll have the center since I have the gameobject as a reference, however I do not know how accurate this would be compared to the CapsuleCast, and there may be issues with objects needing rigidbodies and such. Perhaps instead of OnCollisionEnter id use a physics.CapsuleCheck instead. Not sure.
Any help would be appreciated. Thank you!
Well, you are capsuleCasting in a specific direction from a point. probably forward from the center of your player right? You can calculate the distance between the hitpoint and the origin point of the capsulecast and move your character forward by that distance. It will obviously not be entierly accurate. To improve you could check for the closes point the hitpoint is to the forward vector of the capsulecast, this will get you slightly more accurate (within the radius distance of the actual point). That might not be good enough either.
Then the question becomes why you are trying to do this? If this is a sort of gameplay mechanic where the player is supposed to be able to teleport to the wall it hits, then I can understand it. If this is just to avoid colliding/going through the wall, then there are other far better ways of achieving that (for example by properly moving the character with a CharacterController or a RigidBody).
I am doing this because my rigidbody character sometimes temporarily goes inside a collider and then pops out. Sometimes, like when slipping down a slop, the rigidbody sinks and gets stuck inside the collider. I can fix these issues by raising the timestep for fixedupdate, but I'd rather not do that, so I am looking for other ways to do extra checks to fix collision problems.
$$anonymous$$y rigidbody character moves with addforce and Force$$anonymous$$ode.VelocityChange, and for when my player dashes, it very noticeably goes into the wall and pops back out. Even when it does a simple jump, when it lands it sometimes pops into the floor and back out very slightly.
Okay, I understand. Have you tried playing around with the Collision Detection $$anonymous$$ode? You could also try using the DontGoThroughThings script from the Unity Community page.
$$anonymous$$aybe you try replace capsule cast with several raycasts, one of which you draw from pivot point of your character but outside character's collider of course. Or NOT use Force$$anonymous$$ode.VelocityChange, ins$$anonymous$$d use Force$$anonymous$$ode.Force and you not get any trouble with stucking colliders.
I am currently using Continuous Dynamic for the detection mode.
The DontGoThroughThings script is basically what I am trying to do, except that script is just a single raycast which prevents things from going all the way into walls, but my problem is that I go into the wall a little bit and then pop out. I dont think that script would detect such little interpenetration, I need something that covers my whole player, such as the CapsuleCast.
Using Force$$anonymous$$ode.Force ins$$anonymous$$d of Force$$anonymous$$ode.VelocityChange doesnt fix the problem. $$anonymous$$y character can move fast due to its dash and it glitches into the wall and pops out.
Answer by HiddenMonk · Jan 24, 2015 at 07:07 AM
Today I happened to stumble upon this thread http://forum.unity3d.com/threads/analyzing-and-optimizing-unity-sphere-capsule-casts.233328/ which said that the RaycastHit distance value given by SphereCast and CapsuleCast is actually "... the actual distance the sphere should travel before it hits the hitpoint. This means that if you traveled from the cast origin in the cast direction by the distance provided in the RaycastHit info, you would get the origin of the sphere to which the hitpoint lies on the edge of."
I tested it and it seems to be correct. So you can basically just do this to get the center of a SphereCast or CapsuleCast
Origin is the origin of your cast, directionCast is the direction of your cast, and the hitInfoDistance is the RaycastHit distance value returned by the cast.
public static Vector3 SphereOrCapsuleCastCenterOnCollision(Vector3 origin, Vector3 directionCast, float hitInfoDistance)
{
return origin + (directionCast.normalized * hitInfoDistance);
}
Example usage
RaycastHit hitInfo;
if(Physics.SphereCast(transform.position, .5f, transform.forward, out hitInfo))
{
Vector3 centerOnCollision = SphereOrCapsuleCastCenterOnCollision(transform.position, transform.forward, hitInfo.distance);
}
Your answer
Follow this Question
Related Questions
Platformer2D Player sticks to platform corners 0 Answers
ball's collider sometimes catches an edge and bounces. when ball rolls over two aligned platforms 1 Answer
SphereCast hitting edge of collider, returning "random" normal directions 0 Answers
Setting any height value when performing a capsule cast is impossible? 1 Answer
Obtaining Collision Information (contact points, etc.) WITHOUT affecting physics 4 Answers