Search Unity

I need help making an FPS controller with rigidbody.

Discussion in 'Physics' started by Axisok, Jan 10, 2020.

  1. Axisok

    Axisok

    Joined:
    Jan 8, 2020
    Posts:
    2
    First of all, hi. This is my first post here, if I'm not mistaken.

    I've dedicated the past few days to learning to use Unity and make a very simple game to practice. Or so I thought I would at first, I've been stuck trying to make the player movement work the way I want it to. Tried character controller at first, before realising it doesn't work well with rigidbodies and has no physics at all besides one sided collisions. When I decided it wasn't enough, I tried to make rigidbody work, but because I don't have full control over the player movement it's been really hard to make it work properly.

    I'll list the requirements I've set to myself and I believe the problem will be obvious as you read them.

    • The player can move around until a certain maximum speed, there is acceleration but it's really fast.
    • The player can be accelerated over that speed by forces other than simple movement, such as being launched or a simple dash that sets velocity to a constant.
    • The player can accelerate mid air, but slower.
    • While mid air, the player velocity is not slowed down.
    • On the ground, the player is quickly slowed down to zero velocity when not pressing anything.
    • The player can interact with rigidbodies and rigidbodies can interact with the player.
    • If the player is standing on a slope, he should of course slide along with it.

    In case it wasn't so obvious, I'm trying to have a controller with velocity controlled by physics and still have a lot of control over it. The way I did it with a character controller was to have two completely separate velocity vectors, one for general velocity and other for movement. The movement one is limited to a certain amount but the other is not limited by anything. You can't do that with rigidbodies, so my week of pain begun.

    I made several versions of the controller, with completely different approaches, but none of them fully met all requirements, or got too close to. I even discovered how bunny hopping works while trying to make this happen. So now I'm on my last hope of understanding a way that this could be done. Searching on the internet only gave me super simple controllers you wouldn't like in a full game, especially if movement is minimally important in said game.

    I don't care what would needs to be done, the only thing I care about is a FPS controller that feels really good to play. If you know what I'm missing, if there's a way to make character controller react to physics and slide down slopes, if there's a way to make rigidbodies super responsive, if I'm not even using the components I should, if you have any kind of theory of how it could work, please tell me.
     
  2. Axisok

    Axisok

    Joined:
    Jan 8, 2020
    Posts:
    2
    Update, I solved the problem, it works pretty well considering my other options. If someone's having a problem making a similar controller, here's the way I made it work:

    First, to move around I made a vector that represents the input given by the player, relative to the rigidbody's transform. Second, I multiply that by the movement speed attribute set, I'm currently using 5 and it was 4 at the time. This will be the desired velocity, a value representing the speed the controller will be going for in this update. Third, check if the velocity of the rigidbody is smaller than our desired velocity in each axis separately (I ignore Y as the player never rotates in my tests, but I'm pretty sure it could work on weird angles if projecting velocity on transform.up, right etc.) Lastly, add velocity in the axes where velocity is too small. This has the problem of allowing the player to go a little faster than normal if moving his mouse quickly enough, but considering many games don't even normalize their movement vectors I'm confident no one will notice.

    There's still a problem regarding friction, which makes walls and slopes too sticky to my tastes. My solution for that is zeroing friction on the player and manually making it work the way I want it to. So now I replicated friction almost exactly the way it happens in the default physics engine (my way of doing it might be missing a detail or two, but I haven't noticed it yet), except the player has lower friction on slopes, depending on the angle between it's normal and the player's up vector, and zero on walls and ceiling. It works just fine now, the player slides along walls and slopes, while having perfectly normal friction on the ground.