Search Unity

Suggestions for character controller edge case solutions

Discussion in 'Game Design' started by Not_Sure, Sep 8, 2020.

  1. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,546
    I'm fun-ing around with some character controllers. My own, not the built in Unity one. And I'm running into some edge cases that I'm yet to find proper solutions to.

    I'm doing all my own coding, and avoiding any built in physics other than basic movement and collision.

    As of right now I'm using a 1x1x1 box collider that is suspended 1 unit above the ground with a raycast right out of the middle of it.

    When I jump, the box is stretched to cover the space that the ray would otherwise cover to make sure that the player's feet have to actually make the jump.

    The collider is given no friction to avoid clinging to walls.

    It works pretty well.

    Slopes and steps work pretty much automatically, without having to even do any math.


    The one issue that I'm having, and I see almost all tutorials skipping over, is what happens when you walk to the edge of a platform slowly and fall off.

    The raycast suddenly loses the ground and decides "I'm falling", the player's collider grows and clips the corner, then it hangs (gathering fall speed), and jiggles into place and suddenly drops faster than it should.



    I've kicked around the idea of marking the last known point that it connected, then measuring the current position based off of that point, but I'm just not sure.

    Any suggestions?
     
  2. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Do two raycasts, one at each of the bottom corners, not a single one in the center.

    Also, consider adding "coyote time," a small delay after stepping off the edge of the platform when the player can still initiate a jump even though they're not technically grounded. It make the controller feel more responsive. The player might be a little slow with the jump button, and this adds some forgiveness.

    Matt Thorson (Celeste) did a twitter thread on coyote time and many other controller feel features here.
     
    angrypenguin, Martin_H and JoeStrout like this.
  3. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,546
    Yeah, I'm not quiet up to putting in things like coyote time.

    I had considered this option, but it gets complicated with slopes and 3d.

    EDIT: And I'm explicitly avoiding using a built in Unity character controller. I found it had a couple unfixable edge cases AND this is more about me just doing this as a learning experience.
     
  4. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Fair enough. If you plan to add any forgiveness mechanics like coyote time in the future, at least plan out on paper how you'll implement them. I speak from painful experience that it may entirely change what kind of raycasts, etc., you end up doing. :)
     
    Martin_H likes this.
  5. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    Don't use a box if it's for 3D. Capsule or sphere seem like better options imho.
     
  6. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    Coyote time isn't a forgiveness mechanics unless it's very generous and stretch beyond 100ms. It's because there is a delay between input and visual, and the brain process data generally within 300ms on average, so you need something so that 1 frame delay don't get perceptually damning.

    The problem of character control is universal across 2d and 3d, don't just look for tutorial, look for essay on implementations.

    Havind side sensor is also very common, they push the controller away from wall and prevent hanging. More than one raycast is kinda the norm for anything above simpke adventure games.

    But generally you would have to solve specifically fir your game.
     
    angrypenguin and Martin_H like this.
  7. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,546
    what you’re talking about is really for people who want a simple fix that works “well enough”.

    This method is loaded with lots of edge case problems that are completely unfixable.

    There’s a ton of early developer tutorials on how to do it.

    I’m looking to do something more professional quality, and to experiment.
     
  8. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    Edgecase problems - as in "the edges of the box" - are why I'd take a sphere or capsule as a base. Getting stuck on door frames is some of the most annoying stuff in a shooter, but you'll probable find such edge cases on your own, so enjoy the experimenting!
     
  9. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Getting stuck on door frames is terrible, and rounded bases are a way to let Unity physics handle it, but it sounds like Not_Sure is bypassing physics to do manual raycasting for a more responsive controller (at the cost of more programming work of course). In this case, a box collider is probably easier to use to determine the raypoint origins.
     
    neoshaman likes this.
  10. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    IN an ideal would I would have a cylinder collider rather than box (problem with horizontal movement, corner hanging) or sphere/capsule (problem with cliff hang/slip), because you want smooth contact with wall, but precise contact with floor.

    Mario 64 is all raycast though.
     
    Martin_H likes this.
  11. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    If you're doing raycast-based collision yourself, though, the shape of the visuals is irrelevant. How close you can get to obstacles and what you do about it are all rules that the designer/programmer has to come up with and implement.

    A couple of things I'd think about:

    First, I'd consider sphere casts for a bunch of the cases rather than raycasts. Have the radius roughly match your player's size and it'll prevent abruptly falling off edges. You can even do neat things like compare the hit point to your "center" point to make very precise decisions about when you stick and when you fall.

    Second:
    This suggests that your box still has a collider and active physics? That's fair enough for non-movement stuff, but I wouldn't have two collision/movement systems competing with each other. If your casts say you can fall then you should just fall, and the other colliders shouldn't interfere with that. You'll need PhysX colliders to handle stuff like hit detection, though. (To be fair, I haven't done this kind of thing in quite some time now, so it's possible that PhysX and/or Unity's integration complicates things.)

    If you're doing casts then the math for sliding on slopes, walls, etc. is relatively straightforward. Vector3.Project(...) is a good starting place for a lot of that.

    If you are simulating "forces" then I would also consider tracking current and previous positions and capping velocity based on how far the player actually moved. This will fix issues such as sticking to walls, the roof, etc. if "thrown" into it by an explosion. Potentially even from normal movement and jumping, depending on how you implement momentum.
     
    Martin_H likes this.