• 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 /
  • Help Room /
avatar image
Question by RuskyGaming · Sep 20, 2018 at 08:23 PM · 2d-platformervelocityphysics2daddforce

Determining how much force to add to reach a certain velocity in a certain amount of time and clamping it

So I am working on a 2D player controller with a few things I want to be able to do. Move left and right, jump multiple times, slide down walls and wall jump. Because I want to be able to wall jump I am using RigidBody2D.addForce to move the character around and then checking the characters velocity and clamping it if it goes over the max I want.

I recently found though that the max I set for the velocity isn't really the max the velocity ends up being, say I say it to 3 the velocity ends up being around 9. I noticed this when I was trying to get the wall jumping to work and the player would jump straight up instead of launching away and up from the wall. I take it this happens because the force being added to the player while attempting to move into the wall is too great and basically ignores the forces being exerted on the wall. If I take down the force being applied to the rigidbody when moving it starts feeling weird and takes too long to get to a top speed and I still can't clamp the velocity properly. So what I want to do is work out exactly how much force to apply to get a certain velocity in a certain amount of time and then stop applying force. Drag is disabled and the player slows down when the movement keys are released with a sort of fake friction. I hope this makes sense and isnt too all over the place. Following is my code:

 public float movementForce; //The force applied when attempting to move
 public float maxHorizontalMovementSpeed; //The max speed the character can move
 public float jumpForce; //Force to apply if attempting to jump
 public float groundCheckRadius; //The radius at which to check for ground
 public float groundFrictionLevel; //Float used to determine how much friction is applied when not moving and is grounded
 public float airFrictionLevel; //Float used to determine how much friction is applied when not moving and is not grounded
 public float wallCheckDistance; //The distance at which to check for walls
 public float maxWallSlidingSpeed; //The speed at which the character slides down walls if wallsliding

 public int extraJumps; //The amount of times more than once the player can jump e.g 1 means double jump

 public Vector2 jumpUpWall;

 public LayerMask whatIsGround; //Used to see if what player is touching is ground

 public Transform groundCheck; //The point at which we check for ground
 public Transform wallCheck; //The point from where to fire raycast to check for wall

 private float movementDirection; //Stores horizontal input to determine which direction to move in and face

 private int extraJumpsLeft; //The amount of extra jumps the player ahs left
     
 private bool isFacingRight = true; //Keeps track of if the player sprite is facing right, default is true because player spawns facing right
 private bool isGrounded; //Keeps track of if the player is currently touching ground or not
 private bool isWallSliding; //Used to keep track of if the player is currently sliding down a wall
 private bool canJump; //Keeps track of if the player is currently holding down the space bar or not
 private bool hasJumped; //Keeps track of if the player has jumped or not
 private bool canMove = true; //Keeps track of if the player is currently allowed/able to move or not

 private Vector2 velocity; //Keeps track of the velocity of the player, used for clamping

 private RaycastHit2D wallCheckHit; //Used to keep tack of the player is touching a wall

 private Rigidbody2D rb; //Used to reference the RigidBody2D on player
 private Animator anim; //Used to reference Animator on player

 // Use this for initialization
 void Start () {
     rb = GetComponent<Rigidbody2D>(); //Get's reference to the RigidBody2D attached to the player
     anim = GetComponent<Animator>(); //Get's reference to the Animator attached to the player
     extraJumpsLeft = extraJumps; //Sets initial values for the amount of times more than once the player can jump
 }
 
 // Update is called once per frame
 void Update () {

     Debug.Log(rb.velocity.x);

     movementDirection = Input.GetAxis("Horizontal"); //Set's -1 <= movementDirection <= 1

     if (isGrounded && rb.velocity.y == 0) //Used to make it so the player can jump again after toucing the ground
     {
         canJump = true;
         extraJumpsLeft = extraJumps;
     }

     //Clamp XVelocity
     if (rb.velocity.x > maxHorizontalMovementSpeed) //Right
     {
         rb.velocity = new Vector2(maxHorizontalMovementSpeed, rb.velocity.y);
     }
     else if (rb.velocity.x < -maxHorizontalMovementSpeed) //Left
     {
         rb.velocity = new Vector2(-maxHorizontalMovementSpeed, rb.velocity.y);
     }

     //Clamp YVelocity if wall sliding
     if (isWallSliding && rb.velocity.y < 0)
     {
         if (rb.velocity.y < -maxWallSlidingSpeed) //Clamps downward velocity to max wall sliding velocity
         {
             velocity.y = -maxWallSlidingSpeed;
             velocity.x = rb.velocity.x;
             rb.velocity = velocity;
         }
     }

     //CheckFacing Direction
     if (isFacingRight && movementDirection < 0) //If Sprite is currently facing right but is attempting to move left
     {
         Flip();
     }
     else if(!isFacingRight && movementDirection > 0) //If sprite is currently facing left but is attempting to move right
     {
         Flip();
     }
     //Check jump input
     if (Input.GetButtonDown("Jump"))
     {
         Jump();
     } 
     //Check if wallSliding
     if(wallCheckHit && !isGrounded)
     {
        // Debug.Log("WallSliding");
         isWallSliding = true;
     }
     else
     {
         isWallSliding = false;
     }

     //Set animator parameters
     anim.SetBool("isGrounded", isGrounded);
     anim.SetFloat("xSpeed", Mathf.Abs(movementDirection));
     anim.SetFloat("ySpeed", rb.velocity.y);


 }

 void FixedUpdate()
 {

     //Check if grounded
     isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);

     //Check if touching wall with raycast
     wallCheckHit = Physics2D.Raycast(wallCheck.position, wallCheck.right, wallCheckDistance, whatIsGround);

     //Move Player       
     Vector2 forceToAdd = new Vector2(movementForce * movementDirection, 0); //The force to be applied to the rb2d to make it move, accounts for direction
     rb.AddForce(forceToAdd, ForceMode2D.Force);  

     //Apply friction when player is touching ground and not attempring to move
     if (isGrounded && movementDirection == 0 && Mathf.Abs(rb.velocity.x) > 0) //Ground
     {
         //Debug.Log("Applying Ground Friction");
         velocity = rb.velocity;
         velocity.x *= groundFrictionLevel;
         rb.velocity = velocity;
     } else if (!isGrounded && movementDirection == 0 && Mathf.Abs(rb.velocity.x) > 0) //Air
     {
         //Debug.Log("Applying Air Friction");
         velocity = rb.velocity;
         velocity.x *= airFrictionLevel;
     }
 }

 void Jump()
 {
     //Apply Jump Forces
     if ((canJump || extraJumpsLeft >= 0) && !isWallSliding)
     {
         rb.velocity = new Vector2(rb.velocity.x, 0);
         Vector2 jumpForceToAdd = new Vector2(0, jumpForce);
         rb.AddForce(jumpForceToAdd, ForceMode2D.Impulse);
         canJump = false;
         hasJumped = true;
         extraJumpsLeft--;
     }else if (isWallSliding)
     {
         if(isFacingRight)
         {
             Debug.Log("is attempting to jump up wall");
             Vector2 jumpForceToAdd = new Vector2(jumpUpWall.x * jumpForce, jumpUpWall.y * jumpForce);                
             Debug.Log(jumpForceToAdd);
             rb.AddForce(jumpForceToAdd);
         }
     }
 }

 void Flip() //Flips player sprite to face right direction
 {
     isFacingRight = !isFacingRight; //Set's facing direction so we know which way the sprite is facing
     transform.Rotate(0.0f, 180.0f, 0f); //Rotates the sprite 180 degrees on z axis, this way any child game objects rotate with it.
 }
Comment

People who like this

0 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 tormentoarmagedoom · Sep 21, 2018 at 07:39 AM 0
Share

So long, so many code, so many text...

Try to make is shorter.

PD: Adding force is a vector, is easier to fix the velocity than the vector force.

0 Replies

  • Sort: 

Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta by June 9. Please note, Unity Answers is now in read-only so we can prepare for the final data migration.

For more information and updates, please read our full announcement thread in the Unity Forum.

Follow this Question

Answers Answers and Comments

163 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 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 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 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 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 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 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 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

Choosing speed and direction of AddForce 1 Answer

Trying to add force to an object... is this done correctly? 0 Answers

How do I create Sling-Shot like propulsion? 1 Answer

RigidBody2D velocity randomly drops to zero 1 Answer

Using AddForce for horizontal movement doesn't quite work the way I want it to (2D) 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