Character falling weirdly

I was just messing around and learning some animation recently. Today I was working on the jumping mechanic, and when I was jumping, my character would float down. I am not too sure how to fix it. The video shows what it looks like to jump, and I have provided my code aswell.

i65bh

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public float moveSpeed = 5f;

    public Rigidbody2D rb;

    Vector2 movement; // Stores x , y

    public Animator animator;

    // Update is called once per frame
    void Update()
    {
        //Inputs
        movement.x = Input.GetAxisRaw("Horizontal"); //Give us a values between -1 and 1
        movement.y = Input.GetAxisRaw("Vertical");

        if (movement.y < 0)
        {
            movement.y = 0;
        }

        animator.SetFloat("Horizontal", movement.x);
        animator.SetFloat("Vertical", movement.y);
        animator.SetFloat("Speed", movement.sqrMagnitude);
    }

    void FixedUpdate()
    {
        //Movements
        rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
    }

}

The asset pack I am modifying and using is https://assetstore.unity.com/packages/2d/characters/gothicvania-cemetery-120509

You can alter the gravity on the Rigidbody component. I’m just guessing you’re at about 0.1 on the gravity scale. Try setting it to 1.

5143778--509246--upload_2019-11-5_22-42-16.png

That’s the issue. In the video, my gravity scale is already set to 1. I have tried making it higher but it doesn’t really change it. If it gets too high, then the player can’t even leave the ground.

Have you some surrounding Collider 2D, that’s not defined as “Trigger” (for e.g. the camera bounds) ?
It looks like Unity is trying to solve some collision and can’t really good so it’s shifting away very slowly.

And whats your gravity setting in the project settings ?

Can’t test it at the moment but I think your code causes that behaviour. Specifically this part:

rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);

with rb.MovePosition you are setting both X and Y positions. Easier/better option would be to adjust the velocity where you can adjust only x velocity and leave y velocity as is. Like this:

rb.velocity = new Vector2(movement*moveSpeed, rb.velocity.y);
2 Likes

If you’re continually setting the position, you cannot expect gravity to work as it cannot (easily) change the position. What actually happens is that gravity modifies the velocity but that velocity is ignored by your move so you null the gravity effects or in your case, nearly null it. If you’re going to issue a MovePosition continuously then you need to add in a gravity adjustment to your position so add the gravity vector to the position (also scaled by fixed update) and set gravity scale to zero.

Depending on what else is going on, the actually velocity is probably growing but being continually ignored.

2 Likes

Intersting! How exactly would one go about adding the gravity scale into the MovePosition()? I’m curious to see a code example.

Just add: Physics2D.gravity * Time.fixedDeltaTime

Unfortunately this is affecting position not velocity. If you’re specifically interested in the existing velocity then you can incorporate that. There isn’t a “do it this way” answer here; if you’re overriding position each update and ignoring position changes from the physics changes then you need to incorporate those yourself. This is why MovePosition is typically used for Kinematic motion only.

1 Like

Very informative! I just recently started incorporating MovePos() into my movement scripts; it seems to work great thus far for top-down & side scroll with a non-kinematic controller. I figured I’d try it even though I’m looking forward to 2020 DOT movement in the near future.
Anyway, last question to bother ya with: is MovePosition() similar to Transform.Translate in terms of movement? Since its more of a Kinematic based movement?

No. Transform operations stomp-over physics state and write the transform pose to the body which is the wrong way around. Body poses should be written to the transform with physics in control. Anything else works but only because we’re forced to follow what the user is asking to be done. It’s not how you should work though; if you add a Rigidbody you’re putting it in control of the Transform (that’s one of its primary roles).

Anyway, Transform translate modifies the Transform position which (eventually) repositions the RB and cancels any interpolation (it can’t interpolate to a potentially large position change so it’s just stopped). You can also cause tunneling (passing through colliders) because you’re just jumping from position to position.

MovePosition causes the body to move to the position but does work with continuous col-det, doesn’t affect interpolation. All it really does (at least in 2D) is calculate the temporary velocity required to move to the position during a single physics set. For 2D it also does stuff like temporarily removes drag etc. Collisions can happen en-route to the position and for dynamic objects in 2D they’d collide. 3D (physx) has a built-in method to deal with this but for 2D (Box2D) I had to create the behaviour from scratch.

1 Like