Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Joe Bunda · Jun 04, 2013 at 07:43 PM · physicscapsulecast

Is the CapsuleCast function broken?

Hi all,

I can't get Physics.CapsuleCast to work correctly at all. My goal is to do a basic check to see if a vertically-oriented, non-rotating capsule collider (That represents a 2-dimensional game character) is touching the ground (Represented by a cube) for a jump check. Here's the function I'm using, complete with my original code to perform this task which is commented out (But it did work faithfully).

The behavior I experience is that the function only returns true if the collider is floating about 0.5 units above the floor. If in contact with the floor, it returns false. If it is in the floor (for testing, I turned the collider off), then it returns false. If I move it further away from the floor than about half a unit, it returns false. If I adjust the radius that is passed into the function to account for the half unit disparity, it returns false. If I swap the two capsule points, it returns false.

In short, no matter which order I pass the two points, and no matter what radius I pass, and no matter how far I sweep the test, it only returns true if the collider is around 0.5 units away from the floor. It only seems to return true if the floor is on the very edge of the test! This makes no sense at all, and after reading documentation from other posters about this function, I'm led to believe that it's been broken from some time and hasn't been fixed for several versions of Unity.

I also checked the Physics settings in the editor, and it has a tolerance of 0.01.

Can anybody help? Am I using the wrong function here? Is the documentation inaccurate?

 private bool isGrounded () {
     /*
     float realDistance = myGameObject.collider.bounds.extents.y + 0.1f;
     if (    Physics.Raycast(myGameObject.transform.position, -Vector3.up, realDistance)
         ||     Physics.Raycast(new Vector3(myGameObject.transform.position.x + myGameObject.collider.bounds.extents.x, myGameObject.transform.position.y, myGameObject.transform.position.z), -Vector3.up, realDistance)
         ||     Physics.Raycast(new Vector3(myGameObject.transform.position.x - myGameObject.collider.bounds.extents.x, myGameObject.transform.position.y, myGameObject.transform.position.z), -Vector3.up, realDistance)) {
         return true;
     }
     else {
         return false;
     }
     */
     CapsuleCollider collider = myGameObject.GetComponent<CapsuleCollider>();
     Vector3 position = myGameObject.transform.position;
     Vector3 point1 = new Vector3(position.x, position.y - collider.height*0.5f+collider.radius, position.z);
     Vector3 point2 = new Vector3(position.x, position.y + collider.height*0.5f-collider.radius, position.z);
 
     //Debug.DrawLine (point1, point2, Color.red);
     if (Physics.CapsuleCast(point1, point2, collider.radius, Vector3.down, 0.1f)) {
         return true;    
     }
     else {
         return false;    
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Owen-Reynolds · Jun 04, 2013 at 08:42 PM

The two points in a capsule cast do not include the radius. They are the top and bottom of just the cylinder part. That's from memory, but also in the docs (which I did not read back then): "The capsule is defined by the two spheres with radius around point1 and point2"

So starting 0.5 units above the floor is actually scraping the ground (assuming a standard 0.5 radius.)

The other part is that *casts don't hit things they start inside, and w/o realizing the radius went 0.5 lower, many of your casts probably started below ground. My guess is shooting it just as it skims the ground might be hitting a tiny bump, or just being a weird edge case (technically, if I scrape against something, I am hitting it, sort of.)

Fix would be not to add the radius -- just 1/2 the height. If you look at Ex in the docs, they calculate p1 and p2 using half the height, no radius .

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joe Bunda · Jun 04, 2013 at 09:38 PM 0
Share

I appreciate the response Owen, but if you look at the code I posted, your suggestion is already how I'm calculating the two starting points... center of the collider, plus half the height, and $$anonymous$$us the radius.

Also, I stated clearly that the "ground" in this case is a cube. I will add here that the cube is not rotated at all, so it is completely flat. There are no tiny bumps to hit.

avatar image Owen-Reynolds · Jun 05, 2013 at 02:46 AM 0
Share

Just noticed you cast a vertical capsule straight down, so it's really only a sphere cast. But still, if you test a "down" capsuleCast with actual numbers, it works fine. Forwards cast seem to have a small bug that if p1.y>p2.y then the top and bottom spheres both have to hit.

But, again, try with some solid numbers. Seems to work fine. I suspect the center of the cast, transform.position may be at your feet?

avatar image Joe Bunda · Jun 05, 2013 at 03:22 PM 0
Share

True, I should be using the center of the collider ins$$anonymous$$d of the game object's transform, but in this case they would be equivalent (The collider is centered at the transform). I did some debugs (printed out the vectors and drew a line that showed where both points are), and the points are indeed plotted correctly. I'm then casting down only 0.1 unit, which should register a collision with the floor... but it doesn't. It only registers as a collision when not in contact with the floor, and the collider is somewhere between 0.5 and 0.6 units above the floor. The radius on the collider is 0.5, and so is the radius on the cast. No parameter I can change alters this outcome.

I'll try again today, starting from scratch. $$anonymous$$aybe I've somehow misinterpreted the documentation, and the points are supposed to be at the EDGES of the capsule, not WITHIN the capsule. I saw another post regarding that yesterday.

avatar image Joe Bunda · Jun 05, 2013 at 04:22 PM 0
Share

Alright, so I tried from scratch using a spherecast ins$$anonymous$$d of a capsulecast, and the results are worse. The spherecast doesn't seem to register anything at all!

Am I doing something wrong here, or is there just some bug I'm running afoul of? Here's my latest code.... to test this, make a scene with the following items:

1 - 1x Capsule /w rigidbody & capsule collider

2 - 1x Cube /w box collider, elongated to simulate a floor

Attach the following script to the capsule:

 using UnityEngine;
 using System.Collections;
 
 public class Test : $$anonymous$$onoBehaviour {
     
     CapsuleCollider collider;
     Vector3 point1;
     float radius;
     float distance = 0.1f;
     
     // Use this for initialization
     void Start () {
         collider = gameObject.GetComponent<CapsuleCollider>();
     }
     
     
     // Update is called once per frame
     void FixedUpdate () {
         if (isGrounded() && Input.Get$$anonymous$$eyDown("space")) {
             Debug.Log("Grounded");
             gameObject.rigidbody.velocity = new Vector3(0.0f, 10.0f, 0.0f);    
         }
     }
     
     
     private bool isGrounded () {
         Vector3 position = gameObject.transform.position;
         point1 = new Vector3(position.x, position.y - collider.height*0.5f+collider.radius, position.z);
         radius = collider.radius;
         
         RaycastHit hit;
         if (Physics.SphereCast(point1, radius, Vector3.down, out hit, distance)) {
             return true;
         }
         else {
             return false;
         }
     }
     
     public void OnDrawGizmos () {
         Gizmos.color = Color.red;
         Vector3 sweepPoint = point1 + new Vector3(0, -distance, 0);
         Gizmos.DrawWireSphere(sweepPoint, radius);    
     }
 }




If the capsule is on the ground and you press the spacebar, it should write "grounded" in the log and jump. But it doesn't. This time I'm drawing a gizmo that represents the SphereCast. It appears where I think it should... is the spherecast doing something else internally? Why oh why can't Unity perform actual debugging on these kind of things? I would LOVE to know what's actually happening behind the scenes.

avatar image Owen-Reynolds · Jun 05, 2013 at 04:49 PM 1
Share

FixedUpdate can sometimes miss a Get$$anonymous$$ey operation (officially, they go in update.)

Problem seems to be the physics "sink in" tolerance. The spherecast was fine for me, BUT, not when it was at rest on the ground. A height 2 capsule comes to rest at 0.98, giving the "starts in ground, so ignore it" problem when the sphere/capsule exactly fits in the lower sphere.

A fix is not to cut it so close. Ins$$anonymous$$d of starting at the feet, start in the center and shoot to feet+0.1: start at pos and use a distance of HT/2-radius+0.1.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

The CapsuleCast is broken. 0 Answers

CapsuleCast consistent error in size 1 Answer

How to find the center of mass from capsulecast 0 Answers

How to get the center of a CapsuleCast or SphereCast on collision 1 Answer

Test stationary capsule against colliders in scene. 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges