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 Orggrim · May 20, 2013 at 09:59 PM · movementspeedmove

Getting rid of double movement speed?

Hi, I currently have a ball that rolls around when you press one of the WASD keys

But when I press two simultaneously, it gives the speed from both keys to that direction

Such as (W give 10 speed forward, D gives 10 speed right, but WD gives 20 speed top-right)

Is there a way I can fix this? Please explain your idea if you can too, trying to learn here =D Let me know if there is any additional info you need, Thanks again!

Here is the script I have for movement so far

 var Speed = 0;
 
 function Move()
 {
         if (Input.GetKey (KeyCode.W))
             {
                 rigidbody.AddTorque(Vector3.right * Speed);
                 rigidbody.AddForce(0, 0, Speed);    
             }
             
         if (Input.GetKey (KeyCode.S))
             {
                 rigidbody.AddForce(0, 0, -Speed);
                 rigidbody.AddTorque(Vector3.left * Speed);
             }
             
         if (Input.GetKey (KeyCode.A))
             {
                 rigidbody.AddForce(-Speed, 0, 0);
                 rigidbody.AddTorque(Vector3.forward * Speed);
             }
         
         if (Input.GetKey (KeyCode.D))
             {
                 rigidbody.AddForce(Speed, 0, 0);
                 rigidbody.AddTorque(Vector3.back * Speed);
             }
     
 }
 
 function FixedUpdate()
 {
         if (Input.GetKey (KeyCode.W))
         {
             Move();
         }
         
         if (Input.GetKey (KeyCode.S))
         {
             Move();    
         }
         
         if (Input.GetKey (KeyCode.A))
         {
             Move();
         }
         if (Input.GetKey (KeyCode.D))
         {
             Move();
         }
     
         if (Input.GetKey(KeyCode.Space))
         {
             if (letJump)
             {
                 Jump();
             }    
         }
         
 }    

 
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

3 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by animalphase · May 20, 2013 at 10:25 PM

This is an old, "classic" problem dating back to the beginning of the FPS days. A lot of competitive FPS players use this "trick" in affected games to gain a speed boost. I think it is called "crossing the square", but google is really failing me right now on the subject.

To manage input, instead of checking for key pressed, it is probably better to use Input.GetAxis(). This will return a value of from -1 to 1 in each movement direction, and on the plus side will automatically work with gamepads and joysticks.

So the updated code would go something like this:

 Vector3 direction = new Vector3(0,0,0);
 direction.x = Input.GetAxis("Horizontal");
 direction.z = Input.GetAxis("Vertical");
 direction.Normalize();
 rigidbody.AddForce( direction * Speed );

The above should be the entire contents of the Move() function, aside from any extras that you may put in there. The line "direction.Normalize()" will take the vector that is already pointing in the correct direction and make it only 1 unit long. Thus, you will be able to multiply by "Speed" to get the correct amount.

Comment
Add comment · Show 1 · 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 Orggrim · May 20, 2013 at 11:16 PM 1
Share

Thanks yours really did the trick, just gotta get my Jump function in there somehow and I should be golden

avatar image
2

Answer by TomPendergrass · Feb 03, 2018 at 11:15 PM

A better answer is to use ClampMagnitude. Normalizing your movement vector will always restrict it to a magnitude of 1 (or zero if the vector's magnitude is too small). ClampMagnitude on the other hand will leave your magnitude alone unless it exceeds a your maxLength value. Since you're multiplying by speed, you will want to clamp to the maxLength of 1.

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 Lairinus · May 20, 2013 at 10:09 PM

Vector normalization, for one.

Basically you want to multiply the speed by (roughly) 0.7071 if you're going to be moving on an angle. It has something to do with the length of the vector making the distance traveled ridiculous.

What I would do is organize the code better so that instead of directly calling move after each individual input, you could do something like if ( W && D) Speed * 0.7071, which is the other reason why it's not working.

If you hit 2 buttons with your current code, the function is called twice.

Basically, record all of the input you receive. Then at the end of the function, use another Move() method to actually call the direction. If it's a diagonal, multiply the speed by .7071 (I believe Vector3.normalize does the same thing).

Comment
Add comment · Show 2 · 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 Orggrim · May 20, 2013 at 10:27 PM 0
Share

Ahh I see what you meant about the "calling it twice thing" just deleting all of the stuff in the FixedUpdate and leaving one $$anonymous$$ove() function fixed most of my problem

So I would do 12 if statements at the end of my function to check for multiple keys? Or am I interpreting that wrong?

avatar image Lairinus · May 20, 2013 at 10:39 PM 0
Share

Yes you're interpreting it right, I just don't use Unityscript so I can't give you a source code of what I really meant :(

Look up enums and how to use them ins$$anonymous$$d of if statements. It makes your code cleaner and faster, especially in situations like this when you're frequently checking 8+ options.

Basically with the enum you could do things like:

case(the enum's if-statement) currentDirection = Direction.Left: //do your code

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

16 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

Related Questions

How to make an object without Rigidbody move at the same speed as an object with Rigidbody? 1 Answer

RTS movement with walking animation. 1 Answer

Best Way to make a character move 1 Answer

My object can't move left and right but only jump? 1 Answer

Wheel rotation help cant work out the problem? 0 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