Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Docien · May 10, 2017 at 05:59 PM · movementfpsjumpingfps controllerwalking

Player Falls Much Slower While Moving

I've written a basic movement script for an FPS, but I've come across an issue where if the player is moving while in the air, they almost float back to the ground, but if they are standing still, the jumping functions normally. In addition to this, the jump height is drastically reduced if the player is moving.

Here is my full PlayerMotor script:

 public class PlayerMotor : MonoBehaviour {
 
     public float maxSpeed = 10f;
 
     [SerializeField]
     private Collider _collider;
 
     [SerializeField]
     private Camera cam;
 
     float distToGround;
 
     private Vector3 velocity = Vector3.zero;
     private Vector3 rotation = Vector3.zero;
     private Vector3 cameraRotation = Vector3.zero;
     private Vector3 jumpVelocity = Vector3.zero;
     private Rigidbody rb;
 
     void Start()
     {
         rb = GetComponent<Rigidbody>();
         distToGround = _collider.bounds.extents.y;
     }
 
     // Get value to rotate player and camera by from player controller script
     public void Rotate(Vector3 _rotation)
     {
         rotation = _rotation;
     }
 
     // Get value of movement velocity from the player controller script
     public void Move(Vector3 _velocity)
     {
         velocity = _velocity;
     }
 
     // Get value of jumpVelocity from the player controller script
     public void Jump(Vector3 _jumpVelocity)
     {
         jumpVelocity = _jumpVelocity;
     }
 
     // Get value to rotate camera by from player controller scipt
     public void RotateCamera(Vector3 _cameraRotation)
     {
         cameraRotation = _cameraRotation;
     }
 
     // Check if the player is touching the ground
     public bool IsGrounded()
     {
         return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1f);
     }
 
     // Run every physics iteration
     void FixedUpdate()
     {
         PreformMovement();
         PreformRotation();
     }
 
     // Apply movement to the player's rigidbody
     void PreformMovement()
     {
         if(velocity != Vector3.zero)
         {
             if (rb.velocity.magnitude > maxSpeed)
                 rb.velocity = rb.velocity.normalized * maxSpeed;
             rb.AddForce(velocity, ForceMode.VelocityChange);
         }
         if(jumpVelocity != Vector3.zero)
             rb.AddRelativeForce(jumpVelocity, ForceMode.VelocityChange);
     }
 
     // Apply rotation to camera or player model
     void PreformRotation()
     {
         rb.MoveRotation(rb.rotation * Quaternion.Euler(rotation));
         if (cam != null)
             cam.transform.Rotate(-cameraRotation);
     }
 
 }

From what I've discovered, the issue appears to be where I set the max speed. The y velocity is normalized and then set to the max speed if the player's movement on the x and z axis exceeds the max speed. How would I preserve the y velocity and keep the rigidbody falling at full speed while also setting a max speed to the x and z axis?

Apologies if this is really horribly worded. Thanks in advance :).

Comment
Add comment · Show 7
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 RobAnthem · May 10, 2017 at 06:30 PM 0
Share

This happens when using rigidbody.velocity to move an object. Either create a custom gravity method or use AddForce to move the object.

avatar image Docien RobAnthem · May 10, 2017 at 09:26 PM 0
Share

I've already attempted to use AddForce, albeit not for very long, and creating a gravity method may require a lot of reworking on my end, but that may be something I'll have to try eventually. But is there any way to limit speed on the x and z-axes without limiting the y-axis? $$anonymous$$aybe using $$anonymous$$athf.Clamp()?

This line of code is most likely the source of all my issues: if (rb.velocity.magnitude > maxSpeed) rb.velocity = rb.velocity.normalized * maxSpeed;

avatar image Docien RobAnthem · May 10, 2017 at 09:44 PM 0
Share

Oof, actually, I see what you're saying now. The issue still remains though: how do I set a max speed without using that line of code? Without it, the player can go up to insanely high speeds. I could change how the movement works, but if I do that, I'll have to abandon the fluid movement I was going for.

avatar image RobAnthem Docien · May 10, 2017 at 10:05 PM 1
Share

Honestly, I prefer velocity movement as well, but if you have a method that checks for the object being grounded, then your own gravity isn't difficult. but the downside is you have to check if your jumpheight has been reached before applying the downward velocity.

An alternative could be this.

 public float maxVelocity;
 public Vector3 ClampVelocity(Vector3 vel, float max)
 {
     if (vel.x > max)
     {
         vel.x = max;
     }
     else if (vel.x < -max)
     {
         vel.x = -max;
     }
     if (vel.y > max)
     {
         vel.y = max;
     }
     else if (vel.y < -max)
     {
         vel.y = -max;
     }
     if (vel.z > max)
     {
         vel.z = max;
     }
     else if (vel.z < -max)
     {
         vel.z = -max;
     }
     return vel;
 }
 
 void Update()
 {
     body.AddForce(transform.forward * speed * Time.fixedDeltaTime);
     body.velocity = ClampVelocity(body.velocity, maxVelocity);
 }



Show more comments

2 Replies

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

Answer by Kristinosis · May 11, 2017 at 01:58 PM

Hmm.. I think you could make an intermediate Vector3 to just edit the x and z components of the Vector. So instead of

 rb.velocity = rb.velocity.normalized * maxSpeed;

I would try

 Vector3 vel = rb.velocity.normalized * maxSpeed;
 vel.y = rb.velocity.y;
 rb.velocity = vel;

That way you preserve the y velocity from before but still apply the nomalization and maxSpeed to the x and z components.

Comment
Add comment · Show 3 · 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 Docien · May 12, 2017 at 04:55 AM 0
Share

Oh, this does work well! It does preserve the y-value and sets a cap on the x and z! It does cause a strange issue when jumping though. The player is forced to stop and go straight up, and once the y value is under the max speed, the player can move again. And when the player falls, the y velocity goes over 5, so the player has to stop again (Basically, the player's jump looks like a tall vertical arch if theyre trying to move midair). $$anonymous$$aybe I'll have to activate this code block only when the x and z value are over max speed, so I'll play around with this too! Thank you!

avatar image Docien · May 12, 2017 at 05:02 AM 0
Share

I think I fixed it! Just replaced rb.velocity.magnitude < maxSpeed with manual checks on the x and z axes so that I'm not ever checking for the y.

  if (rb.velocity.x > maxSpeed || rb.velocity.x < -maxSpeed || rb.velocity.z > maxSpeed || rb.velocity.z < -maxSpeed)
             {
                 Vector3 vel = rb.velocity.normalized * maxSpeed;
                 vel.y = rb.velocity.y;
                 rb.velocity = vel;
             }
             rb.AddForce(velocity, Force$$anonymous$$ode.VelocityChange);
avatar image Kristinosis · May 12, 2017 at 05:34 AM 0
Share

Awesome! Glad you could get it working :)

avatar image
0

Answer by robot_rover · May 11, 2017 at 01:55 PM

I believe this is what you are looking for. It applies your desired velocity change, then check to see if you are over your max speed on the xz plane only, and if you are it caps xz movement to the max speed.

          if(velocity != Vector3.zero)
          {
              rb.AddForce(velocity, ForceMode.VelocityChange);
              Vector2 xzMovement = Vector2(rb.velocity.x, rb.velocity.z);
              if(xzMovement.magnitude > maxSpeed)
              {
                 var zxMovementCapped = xzMovement.normalized * maxSpeed;
                 rb.velocity.x = zxMovementCapped.x;
                 rb.velocity.z = zxMovementCapped.z;
              }
          }
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 Docien · May 12, 2017 at 04:51 AM 0
Share

Hm, it seems that Vector2 can only hold an x and y value, so zx$$anonymous$$ovementCapped.z is invalid. I'll play around with this and see if I can make it work for me though, thank you!

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

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Character Movement and Jumping Script? 4 Answers

Carry forward velocity against mouse movements 1 Answer

Sprint and Crouch problem! 1 Answer

How can I make my FPS player move towards the direction it is facing 1 Answer

Why can't I jump and run at the same time? c# 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