Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 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 josephquested · Jul 15, 2015 at 03:35 PM · movementunity5rigidbody2ddiagonal

Disabling diagonal movement in Unity 5 2D? (using C#)

Or rather I should say, "EFFECTIVELY disabling diagonal movement".

There are plenty of Q/As online about this, but I keep encountering the same problem: When moving horizontally (left, for example), I can override the current direction and start moving vertically (by pushing up), which is what I want. But it does not work the other way around! Vertical movement can not override horizontal movement.

 void Update () {
 
          float h = Input.GetAxis("Horizontal");
          float v = Input.GetAxis("Vertical");
           ManageMovement(h, v); 
 }    
 
 void ManageMovement(float horizontal,float vertical) {
 
         if (vertical != 0f) {
                 horizontal = 0f;
                 Vector3 movement = new Vector3 (horizontal, vertical, 0);
                 GetComponent<Rigidbody2D> ().velocity = movement * speed;
                 return;
             } 
 
         if (horizontal != 0f) {
             vertical = 0f;
             Vector3 movement = new Vector3 (horizontal, vertical, 0);
             GetComponent<Rigidbody2D> ().velocity = movement * speed;
             return;
 
         } else {
             Vector3 noMovement = new Vector3 (0, 0, 0);
             GetComponent<Rigidbody2D> ().velocity = noMovement;
         }
     }

If I reverse the order of these if() statements, it reverses the problem. So, that's a clue. But I'm not a great detective. I would love some help!

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 meat5000 ♦ · Jul 15, 2015 at 03:35 PM 0
Share

Whichever executes last will win.

Perhaps think about a 'last change' system which uses 1 variable to indicate the state and your logic populates that field.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Dave-Carlile · Jul 15, 2015 at 03:44 PM

Part of the problem is that you're looking for the direction component that's not zero. Assuming you're using a gamepad it's likely that both directions will be non-zero. The way you have the code structured, the last if will always win. If you add an else before if (horizontal... then the first one that's non-zero will always win.

What will probably work better is for you to compare the direction components against each other, so the bigger one wins.

 if (h > v)
 {
   // input is more horizontal than vertical so move horizontally
 }
 else if (v > h)
 {
   // input is more vertical than horizontal so move vertically
 }
 else
 {
   // don't move
 }
Comment
Add comment · Show 5 · 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 meat5000 ♦ · Jul 15, 2015 at 03:52 PM 0
Share

Yeah comparing to 0 is asking for trouble. Need Dead-Zone.

avatar image josephquested · Jul 16, 2015 at 07:43 AM 0
Share

I'm trying this solution currently, and it's yielding really weird results. $$anonymous$$ovement up and right work, although kind of un-reliably, and movement left and down don't work at all. The part of this solution I don't understand is.. the input is binary right? So either, "key is being pushed" or "key is not being pushed", so if both keys were being pushed, why would if (h > v) or (v > h) be useful? Because if both were being pushed, wouldn't they be equal?

avatar image Dave-Carlile · Jul 16, 2015 at 05:59 PM 0
Share

You want $$anonymous$$athf.Abs(h) > $$anonymous$$athf.Abs(v) to deal with the left and down movement.

As to your second question, it pretty much depends on the behavior you want. If both are being pushed then yes, movement would stop using my code when using the keyboard. What exactly do you want to happen? So far we only know that you don't want to move diagonally.

If the player is holding down the right key and then presses the up key while continuing to hold down the right key, what is the behavior you want? I assume it's whatever the most recent input was?

avatar image Dave-Carlile · Jul 16, 2015 at 06:24 PM 0
Share

Using my previous assumption, you need to track the state changes for each direction - transitioning to horizontal or vertical, and transitioning out of horizontal or vertical...

I haven't tested this, but I think it should cover what you're looking for. The key is detecting the transitions, e.g. "If we have horizontal input this frame, but we didn't last frame, then zero out the vertical component and move horizontally".

If vertical and horizontal input are both added in the same frame, one of them has to win, and that will depend on the order in the code - the last one will win.

 Vector2 direction;  // this keeps track of our current movement direction
 
 bool WasHorizontal { get { return $$anonymous$$athf.Abs(direction.x) != 0; } }
 bool IsHorizontal { get { return $$anonymous$$athf.Abs(h) != 0; } }
 bool WasVertical { get { return $$anonymous$$athf.Abs(direction.y) != 0; } }
 bool IsVertical { get { return $$anonymous$$athf.Abs(v) != 0; } }
 
 
 void Update()
 {
   // if horizontal movement was removed this frame then clear the horizontal component
   if (!IsHorizontal and WasHorizontal)
   {
     direction.x = 0;
   }
   
   // if vertical movement was removed this frame then clear the vertical component
   if (!IsVertical and WasVertical)
   {
     direction.y = 0;
   }
   
   // if horizontal movement was added this frame then switch to horizontal
   if (IsHorizontal && !WasHorizontal)
   {
     direction = new Vector2(h, 0);
   }
 
   // if vertical movement was added this frame then switch to vertical
   if (IsVertical && !WasVertical)
   {
     direction = new Vector2(0, v);
   }
   
   // TODO : apply the direction vector to the object position
 }

avatar image josephquested · Jul 17, 2015 at 08:26 AM 0
Share

Hey Dave! It looks like you put a lot of thought into this, thank you so much. I copied the code almost entirely, although there were a couple errors I got thrown. First 'v' and 'h' were out of scope for use in the bools, that was an easy fix, I just brought them up and declared them outside of update() first. Then I got errors for if (!IsHorizontal and WasHorizontal) and if (!IsVertical and WasVertical). It was not cool with the use of and; (I changed it to &&) I assumed that was what you meant?

So, long story short. It runs, but unfortunately nothing has changed! When you're pressing right, the player moves right, you can then push up (while still holding right) and start moving up. Which is exactly the desired response, new keys should override old keys. But, vertical movement still can't be overridden by horizontal movement! I can't work it out. :/

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

2D Character suddenly stops moving for no given reason 1 Answer

How do you modify the extra step / finishing step in FPSController 0 Answers

Tracking HTC Vive Controller Motion Direction? 1 Answer

Simple Rigidbody2D movement and jump 0 Answers

2D "Platformer" Movement Problems 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