Search Unity

Rigidbody Controller and controlling in air movements

Discussion in 'Scripting' started by smasters654, Sep 22, 2019.

  1. smasters654

    smasters654

    Joined:
    Dec 20, 2013
    Posts:
    46
    Hello,

    I am hoping someone can point me in the right direction here. I have a sphere rigidbody character controller and I have everything working except the in-Air movement. The problem I am having is my sphere upon jumping will jump really far in the direction of travel. I want to some how slow or dampen in air movement kind of like 3d Super Mario games. I want to have more control in the air but I don't want the player to be able to jump too far in one direction. It would be easy if I could control drag on separate axis. I don't want to affect the Y velocity. Any Ideas? Thanks!

    My code is here on unity answers. I am on my phone right now so I can’t copy it here.


    https://answers.unity.com/questions/1666566/rigidbody-controller-and-controlling-in-air-moveme.html
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    If you want to get a very specific mario-like feel to your platform jumper, using built-in physics is going to be very tricky. The physics engine is a generic system, intended to be realistic, and as such it is subject to frictions and torques and other things that will constantly interfere with your movement tuning in unpredictable ways.

    I would just leave the RB in place so you can use colliders, mark the RB as kinematic, keep track of your own velocity, and then use the .MovePosition() method on the RB to move your player around the way you want him to move.

    This means you will need to have routines to handle on-ground motion, jumping motion, what happens when you climb a ladder, hit ice or sticky stuff, hit a bouncy wall, hit a non-bouncy wall, etc., or when you bop off the head of an enemy, get caught in an updraft, etc.

    But thats exactly what Nintendo code is doing in order to get their exquisitely-tuned play feel. And you have to admit, Nintendo gets the controls 100% right in a way that is amazing every time, and they only do that by meticulously specifying in code what happens in all states of movement.
     
  3. smasters654

    smasters654

    Joined:
    Dec 20, 2013
    Posts:
    46
    Hi Kurt,

    I forgot to mention my player is a sphere. So I'm not sure .MovePosition() will work for what I am doing as I want the sphere to roll and look realistic doing it. But I will take a look at that and the docs on MovePosition, just in case.Thank you for the idea.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    Rolling motion will be easier to get with Unity physics, but it won't feel like Sonic hitting the ground. In a real physics simulation, when you graze something, Unity will convert some of your lateral velocity into rotational velocity, so your player will slow down in order to spin.

    If the sphere radius is constant, it may prove easier to simply convert lateral motion into spinning rate (only when touching something) but only use that to display rotating geometry, while the underlying GameObject that the RB is on doesn't spin. Otherwise you'll be forever trading linear velocity for rotational velocity, which is going to make it very difficult to tune.
     
  5. smasters654

    smasters654

    Joined:
    Dec 20, 2013
    Posts:
    46
    My sphere radius is constant. Is what your saying, I should use .MovePosition, but when touching the ground && on the move, get the movement velocity and covert it to spinning rotation on the child object(Sphere Geometry)?
     
  6. smasters654

    smasters654

    Joined:
    Dec 20, 2013
    Posts:
    46
    I got this to work but then I have no gravity or collision detection, so I don't think this is the route I should go.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    Gravity is easy:

    Code (csharp):
    1. Vector3 velocity;
    and then

    Code (csharp):
    1. velocity += Physics.gravity * Time.deltaTime;
    2. var newPos = transform.position + velocity * Time.deltaTime;
    Now drive it with .MovePosition() and you get collision notification too, assuming all other normal criteria for collisions have been met. You still need to adjust your velocity to zero when you hit down on the ground and do the decisions related to speed, but you DO get the collision information as usual in your Monobehaviors on the RigidBody-equipped GameObject.
     
  8. smasters654

    smasters654

    Joined:
    Dec 20, 2013
    Posts:
    46
    I have my rigidbody set to kinematic because if I don't I get weird behavior if I roll into a static collider. I don't know if that makes a difference in this scenario.