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 GoMeteoroGo · Jan 07, 2014 at 03:14 AM · 2d collision

2D Collision Detection with Raycasting

I'm kind of stumped here.

I'm trying to set up movement controls for a basic top-down style game. Right now, I've got the following code to control player movement and collision detection with wall objects:

 Vector3 vertSize = new Vector3(0f, 0.875f, 0f);
     Vector3 horSize = new Vector3(0.5625f, 0f, 0f);
     Vector3 vertSpeed = new Vector3(0f, 0.01f, 0f);
     Vector3 horSpeed = new Vector3 (0.01f, 0f, 0f);
 
     
     void Update () 
     {
         Vector3 spot = transform.position;
         RaycastHit2D hit1;
         RaycastHit2D hit2;
 
         if (Input.GetKey ("s")||Input.GetKey ("down"))
         {
         hit1 = Physics2D.Raycast ((spot+(horSize/2)),-Vector2.up,((vertSize[1]/2)-vertSpeed[1]));
         hit2 = Physics2D.Raycast ((spot-(horSize/2)),-Vector2.up,((vertSize[1]/2)-vertSpeed[1]));
         
             if ((!hit1 && !hit2) || ((!hit1 && (hit2.collider.tag != "block"))) || (!hit2 && (hit1.collider.tag != "block")))
         {
                 transform.Translate (-vertSpeed);
             }
         }
 
         if (Input.GetKey ("w")||Input.GetKey ("up"))
         {
         hit1 = Physics2D.Raycast ((spot+(horSize/2)),Vector2.up,((vertSize[1]/2)+vertSpeed[1]));
         hit2 = Physics2D.Raycast ((spot-(horSize/2)),Vector2.up,((vertSize[1]/2)+vertSpeed[1]));
 
             if ((!hit1 && !hit2) || ((!hit1 && (hit2.collider.tag != "block"))) || (!hit2 && (hit1.collider.tag != "block")))
             {
                 transform.Translate (vertSpeed);
             }
         }
 
         if (Input.GetKey ("a")||Input.GetKey ("left"))
         {
 
         hit1 = Physics2D.Raycast ((spot+(vertSize/2)),-Vector2.right,((horSize[0]/2)-horSpeed[0]));
         hit2 = Physics2D.Raycast ((spot-(vertSize/2)),-Vector2.right,((horSize[0]/2)-horSpeed[0]));
 
             if ((!hit1 && !hit2) || ((!hit1 && (hit2.collider.tag != "block"))) || (!hit2 && (hit1.collider.tag != "block")))
             {
                 transform.Translate (-horSpeed);
             }
         }
 
         if (Input.GetKey ("d")||Input.GetKey ("right"))
         {
         hit1 = Physics2D.Raycast ((spot+(vertSize/2)),Vector2.right,((horSize[0]/2)+horSpeed[0]));
         hit2 = Physics2D.Raycast ((spot-(vertSize/2)),Vector2.right,((horSize[0]/2)+horSpeed[0]));
         
             if ((!hit1 && !hit2) || ((!hit1 && (hit2.collider.tag != "block"))) || (!hit2 && (hit1.collider.tag != "block")))
             {
                 transform.Translate (horSpeed);
             }
         }
     }
 }
 

(there's almost certainly a cleaner/more elegant way to write this code, but for the moment I'm just concerned with making it work)

The idea here is that when a direction key is pressed, the player character object casts two rays, one on either of its sides, with a length equal to half of its size plus the distance the object can travel in a single frame. If neither of the rays hit any object, or if the object(s) that they hit do not have a "block" tag, then the player character is allowed to move in that direction this frame.

To test this, I have the player character in a game world with a single square object with the "block" tag. The script works just fine if I approach the square from the bottom or from the left. If I approach it from the top or from the right, however, the character just SLIGHTLY overlaps the block before stopping, which in addition to being wrong visually makes it so that the character can't move tangent to the surface of the block. If I "walk" onto the top of the block, for instance, then the bottom of the sprite overlaps the block slightly. From there, if I try to move left or right, the lower raycast will detect the block, and the character is unable to move.

The part I'm not getting is why this only happens when I approach the block from the top or from the right, and not when I approach the block from any direction. the script for walking left is identical to the script for walking right; the only difference is a few negative signs. At least if I was running into this problem regardless of which direction I approached the block from I could assume that there was an error in my script, but the same exact code works perfectly in one context but screws up in another. I have no idea why that is.

Comment
Add comment · Show 1
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 Eric5h5 · Jan 07, 2014 at 03:28 AM 0
Share

Not that it's related, but you need to use Time.deltaTime in order to prevent your movement from being framerate-dependent.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Aelrift · May 14, 2017 at 04:46 PM

You just need to use a collider for your player and every object it collides with and then make it so that wahenever it hits one it adds negative speed ( say if your player is going at 2 then when he hits a wall you'd add -2 speed so it would stop him from moving)

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

20 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 avatar image avatar image avatar image avatar image avatar image

Related Questions

Scale object, collision not working 2 Answers

How can I drag and drop 2D objects with the mouse without passing through other objects. 1 Answer

How do I properly handle a collision between a ball and a rectangle in 2D? 3 Answers

Health Bar Doesn't Go Down When Colliding With Enemy 2 Answers

Infinite Runner Live Training 2d collisions not working 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