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 zeteginara · Feb 28, 2014 at 03:44 PM · diagonalhorizontal movement

How do I automatically go diagonally when hitting a diagonal?

So, I'm starting a top-down 2D RPG sort of game, with free-form movement instead of, well, large-grid specific movement. I got a 'basic guy moving across the screen colliding with a tilemap. However, when I hit a diagonal, I slow way down.

I seem to be doing this:

alt text

When I want to do this:

alt text

This seems to be a problem that should have a simple solution. Ideas?

wrong.png (2.1 kB)
right.png (1.8 kB)
Comment
Add comment · Show 5
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 robertbu · Feb 28, 2014 at 04:26 PM 0
Share

Total guessarouni without more context, but perhaps you should rotate your 2D character so that it is aligned with the normal of the surface and make sure the code is moving the character on its forward not world forward. That way your code won't be forcing the character into the object. Or you could raycast and take into account the slope when you apply force.

avatar image zeteginara · Feb 28, 2014 at 04:33 PM 0
Share

Are there any examples on how to do this?

Right now my movement code is very simple.

float moveHorizontal = Input.GetAxisRaw("Horizontal"); float moveVertical = Input.GetAxisRaw("Vertical");

$$anonymous$$ovement = new Vector2(moveHorizontal, moveVertical); rigidbody2D.velocity = $$anonymous$$ovement * Speed;

avatar image zeteginara · Mar 01, 2014 at 04:29 AM 0
Share

I've been working on this and scouring the internet all day, and getting frustrated.

Here's all the code that I have:

 void FixedUpdate()
     {
         float moveHorizontal = Input.GetAxisRaw("Horizontal");
         float moveVertical = Input.GetAxisRaw("Vertical");
 
         $$anonymous$$ovement = new Vector2(moveHorizontal, moveVertical);
         $$anonymous$$ovement.Normalize();
         rigidbody2D.velocity = $$anonymous$$ovement * Speed;
     }
 
 
     void OnCollisionEnter2D(Collision2D other)
     {
         Normal = other.contacts[0].normal;
         rigidbody2D.velocity -= Normal * Vector2.Dot(rigidbody2D.velocity, Normal);
     }

It seems that no one has a good answer to this, and I imagine this is a relatively standard problem. What am I doing wrong?

avatar image nesis · Mar 01, 2014 at 08:01 AM 0
Share

Your OnCollisionEnter2D() code is making your character move at a new velocity parallel to the surface they hit. However, that new velocity is effectively projected from your old rigidbody2D.velocity, and onto the surface (I'll leave out the mathsy explanation for simplicity's sake). What's important is that this just means that for the new velocity, you're keeping only the portion of rigidbody2D.velocity that points in the same direction as the surface (see here for an explanation of vector projection).

Usually this is perfectly acceptable behaviour for movement - eg, walking into walls in an FPS or 3rd person game. However, if you want to maintain your ideal movement speed, in OnCollisionEnter2D() you'll need to take the new velocity, normalize it, and multiply it by your character's speed. This should do the trick.

If you're feeling tricky, you could also add code to OnCollisionEnter2D() that lets the player move until they're just touching the surface, then moves them in a direction parallel to the surface.

avatar image zeteginara · Mar 01, 2014 at 04:37 PM 0
Share

Actually, it seems the problem was that the velocity would be set once when the collision first happened, and then the FixedUpdate() loop would override it.

The original calculation of:

 rigidbody2D.velocity -= Normal * Vector2.Dot(rigidbody2D.velocity, Normal);

Works; we don't need to multiply speed because speed is already calculated into the velocity, and we use the velocity in the equation.

Here's my new code:

 void FixedUpdate()
 {
     float moveHorizontal = Input.GetAxisRaw("Horizontal");
     float moveVertical = Input.GetAxisRaw("Vertical");

     $$anonymous$$ovement = new Vector2(moveHorizontal, moveVertical);
     $$anonymous$$ovement.Normalize();
     rigidbody2D.velocity = $$anonymous$$ovement * Speed;
     if (Colliding && $$anonymous$$ovement == Record$$anonymous$$ovement)
     {
         rigidbody2D.velocity -= Normal * Vector2.Dot(rigidbody2D.velocity, Normal);
     }
     else
     {
         Record$$anonymous$$ovement = $$anonymous$$ovement;
     }
 }

 void OnCollisionEnter2D(Collision2D other)
 {           
     Normal = other.contacts[other.contacts.Length - 1].normal;
     Normal.Normalize();
     OppositeNormal = Normal * -1;
     
     if ((OppositeNormal != $$anonymous$$ovement) && (Colliding != true))
     {
         Colliding = true;
     }
     else
     {
         Colliding = false;
     }
 }
 void OnCollisionExit2D(Collision2D other)
 {
     Colliding = false;
 }

However, then I had another problem. Well, several other problems. I've resolved some, but one remains.

If I am up against a wall, and moving parellel to it so that my collider is 'just touching' the wall, and I hit a diagonal from there, then I move just as slow as if my new code didn't exist. After lots of debugging, I found that we are detecting a new collision, but if I try to get the normal of this new collision, I end up with the normal of the old collision (the wall I was sliding against) I don't know if this is a bug in Unity, or what.

I even tried changing my code to "Normal = other.contacts[other.contacts.Length - 1].normal;", assu$$anonymous$$g that would get the last element of the array (latest), but no dice, same incorrect normal.

So, any ideas?

1 Reply

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

Answer by zeteginara · Mar 03, 2014 at 04:11 PM

I finally resolved this! My gut feeling was right: I was overthinking it.

Step 1: Remove all of the code example above and just have a simple:

     void FixedUpdate()
     {
         float moveHorizontal = Input.GetAxisRaw("Horizontal");
         float moveVertical = Input.GetAxisRaw("Vertical");
 
         movement = new Vector2(moveHorizontal, moveVertical);
         movement.Normalize();
         rigidbody2D.velocity = movement * Speed;
     } 

Step 2: In your assets folder, go to Create > Physics2DMaterial. Create one.

Step 3: Click your new material, and call it whatever you want. I called it "Frictionless". Set Friction to 0, and make sure "Bounce" is 0.

Step 4: Drag your new material to any of the "Physics Material (2D)" fields in any of the objects involved in the equation.

You're done!

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

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

Related Questions

Diagonal moving is faster .Help in solving a bug! 1 Answer

Drag object with mouse in diagonal direction 0 Answers

Swapping Horizontal Input for Mobile 0 Answers

Diagonal Wall Jump 0 Answers

UnityException: Input Axis Horizontal is not setup. 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