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 ArcaneTheWoof · Jul 03, 2012 at 08:41 PM · 2dcollisionphysics

Size and Position of BoxCollider

I'm trying to code a basic collision system that detects when an actor hits a platform and stops the actor on the platform—basic 2D platformer stuff. I'm using Orthello2D. The way it should work is as follows:

2 RayCasts are fired out from the left and right sides of the actor's collider, both from the bottom of the actor's collider (this is very important). The length of the RayCast is equal to the absolute value of the actor's current y velocity (since they're moving down, it would be negative). If a collision is detected, the actor is moved to the point of impact plus half of the collider's size (taking into account that the collider's size is relative to the actor) and sets various variables (like airborne and velocity) to cease falling.

The problem I've been seeing during debugging is that the RayCasts are not firing from the bottom of the collider, but rather from slightly above said bottom, and I think that's messing up all the hit detection/translation that needs to happen. This code works perfectly if I use hard numbers instead of calculating based on size (but I'm using size so I can use the same code for all actors regardless of sprite size—less error prone), so I think I'm missing something about how size and position of colliders is determined. Could someone take a look at my code and tell me what I'm not getting?

 int platformMask = 1 << 8;
 RaycastHit hit;

 // colliderCenter should be the collider's position in the scene
 // myCollider is the collider attached to the actor using GetComponent<BoxCollider>();
 Vector3 colliderCenter = thisTransform.position + myCollider.center;
 // colliderSize should be the collider's size, factoring in scale of the actor
 Vector3 colliderSize = Vector3.Scale(thisTransform.localScale, myCollider.size);

 // colliderBottom here is the problem; it's too high!
 // How do I get the actual bottom of the collider (y value)?
 float colliderBottom = colliderCenter.y - (colliderSize.y / 2);
 float colliderLeft = colliderCenter.x - (colliderSize.x / 2);
 float colliderRight = colliderCenter.x + (colliderSize.x / 2);
 float rayLength = Mathf.Abs(velocity.y * Time.deltaTime) > 0 ? Mathf.Abs(velocity.y * Time.deltaTime) : 0.01f;
 
 if (Physics.Raycast(new Vector3(colliderLeft, colliderBottom, colliderCenter.z), Vector3.down, out hit, rayLength, platformMask)
     || Physics.Raycast(new Vector3(colliderRight, colliderBottom, colliderCenter.z), Vector3.down, out hit, rayLength, platformMask))
 {
     // Momentum is 1 if velocity is positive, -1 if negative, and 0 if 0
     // In this case, we're checking the the actor is falling
     if (Momentum.y < 0) {
         // Move the actor to its box collider height above the hit point
         thisTransform.position = new Vector3(thisTransform.position.x, hit.point.y + (colliderSize.y / 2) - myCollider.center.y, 0f);

         // Ground the actor (for acceleration and animation)
         airborne = isJumping = false;
         
     }
 } else {
     // Set the actor as airborne (for acceleration and animation)
     airborne = true;
 }
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

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by ArcaneTheWoof · Jul 03, 2012 at 09:13 PM

I believe I solved the problem, but feel free to weigh in, this is by no means the best solution. Here's the adjusted code and what I discovered.

 int platformMask = 1 << 8;
 RaycastHit hit;
 
 Vector3 colliderCenter = Vector3.Scale(thisTransform.localScale, myCollider.center);
 Vector3 colliderPosition = thisTransform.position + colliderCenter;
 Vector3 colliderSize = Vector3.Scale(thisTransform.localScale, myCollider.size);
 
 float colliderBottom = colliderPosition.y - (colliderSize.y / 2);
 float colliderLeft = colliderPosition.x - (colliderSize.x / 2);
 float colliderRight = colliderPosition.x + (colliderSize.x / 2);
 // rayLength needs to be > 0;
 float rayLength = Mathf.Abs(velocity.y * Time.deltaTime) > 0 ? Mathf.Abs(velocity.y * Time.deltaTime) : 0.1f;

 // SPECIAL NOTE
 if (Physics.Raycast(new Vector3(colliderLeft, colliderBottom + 0.1f, colliderCenter.z), Vector3.down, out hit, rayLength + 0.1f, platformMask)
     || Physics.Raycast(new Vector3(colliderRight, colliderBottom + 0.1f, colliderCenter.z), Vector3.down, out hit, rayLength + 0.1f, platformMask))
 {
     if (Momentum.y < 0) {
         thisTransform.position = new Vector3(thisTransform.position.x, hit.point.y + (colliderSize.y / 2) - (colliderCenter.y), 0f);
 
         airborne = isJumping = false;
     }
 } else {
     airborne = true;
 }

Problem one is that the center of the collider needs to be scaled to the actor's size as well (hence the addition of a colliderPosition variable as well as a modified colliderCenter. Problem two is that a collision hit occurs at the edge of a box, not inside, and so when the collider is literally smack against the side, a RayCast of any length will not produce a hit. The if clause under SPECIAL NOTE in the code has been adjusted to cast the ray from slightly above the bottom of the collider, for a length equally longer than the y velocity.

Hope this helps others!

Comment
Add comment · 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
0

Answer by kramerica500o · Mar 27, 2014 at 04:38 PM

Lines 4 & 5 don't take rotation of the parent object into account, which will give an incorrect world position if it's rotated. I did it like this:

 Vector3 colliderPos = gameObject.transform.TransformPoint(collider.center);
 Vector3 screenPos = camera.WorldToScreenPoint (colliderPos);
Comment
Add comment · 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

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Is there a solution to when colliders bypass? 2 Answers

Prefab instantiated by code, collision does not work 0 Answers

Unity 4.3 CharacterController collision with physics 2D not working 1 Answer

2D Collider aren't exact? 6 Answers

Script calling onCollisionEnter2D and onTriggerEnter2D while disabled 1 Answer


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