2
\$\begingroup\$

I am working on a character controller for a 3D platformer in Unity. I cannot find an approach that satisfies me.

I have experimented with these approaches in order to learn about their virtues and pitfalls:

  1. Rigidbody + CapsuleCollider + native physics system (gives you something like Fall Guys)
  2. Rigidbody + CapsuleCollider + custom velocity handling, only using physics system to resolve collisions (this method is illustrated in Catlike Coding tutorial here)
  3. Built-in CharacterController
  4. Custom character controller that uses Unity methods to detect geometric collisions, but does its own collision resolution via depenetration (this method is illustrated in Roystan Ross tutorial here)

See also this video by iHeartGameDev summarizing different approaches.


For my particular use case, each one of these has been better than the last.

After following Roystan's tutorial, I am a big fan of the pushback method of handling collision. Rather than use casts to catch collision before you move your object, you move your object, then find collisions, then resolve them using depenetration.

Roystan's method represents the character as a stack of three spheres for the same reason people favor capsule colliders in 3D: it makes handling slopes much easier (and also because depenetration is easier when you think in terms of spheres).

But the thing I am struggling with is that I don't want the player to be able to slide up or down ledges when traversing them.

Basically, when jumping up or walking off a ledge, I want my character to be treated as a box.

So I am struggling to find a way to accommodate both of the following:

  • I want to support sloped MeshCollider ground (not too noisy, but will definitely be possible to have 4 collision points at a time)
  • I want ledge traversal (up and down) to treat my player as a box

Here are diagrams illustrating what you normally get with a capsule, versus what I want.

Down ledge: enter image description here

Up ledge: enter image description here

My thinking is that I have two options:

  1. Represent the character as a box and use box depenetration techniques to move him along sloped ground (for example, using Unity's ComputePenetration())
  2. Represent the character as a capsule (or stack of three spheres like in Roystan's tutorial) and add special case logic to get the boxy ledge traversal I want

One problem I can foresee with approach 1 is properly doing the depenentration on noisy sloped ground, and one problem I can foresee with approach 2 is properly writing the special cases. (My game is relatively low-poly and retro-styled, so I wouldn't mind the player not appearing perfectly flush with slopes that comes with the box representation of approach 1.)

In any event, I am just looking for advice on how to proceed with this problem. How can I get the boxy handling of ledges while also getting traversal on sloped MeshCollider terrain.

Is either of these approaches better than the other for what I am after, and is there an alternative approach I haven't considered?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Why not use both a box and a capsule collider (or the system that works best for you from your list)? A small raycast downwards will decide which one to use. As soon as the distance is greater than X, use the box collider just for handling the jumping edge cases \$\endgroup\$
    – Zibelas
    Commented Sep 21, 2023 at 20:34
  • \$\begingroup\$ @Zibelas, that's a good idea, I will give it a shot and report back. Initially, I was thinking the approach you describe would cause issues when walking off a ledge, since there'd be one frame before CharacterController realizes player is walking off a ledge and switches to box mode, allowing the player's capsule to start sliding down the ledge before we switch to box mode, at which point the box depenetration would snap the player to the top of ledge however far they managed to slide down the previous frame. \$\endgroup\$
    – DyingIsFun
    Commented Sep 23, 2023 at 16:25
  • \$\begingroup\$ You can have two raycasts (in front and in the back) for switching (compared to one Center one). The capsule should as well only slide down the edge once it is more than half over it. More than enough time to detect the edge and switch \$\endgroup\$
    – Zibelas
    Commented Sep 23, 2023 at 19:20
  • \$\begingroup\$ Yeah, it seems very promising. Here is footage of what I have managed so far, using a single raycast from midbottom to determine whether we should be using capsule or box. i.imgur.com/gQWSSyP.gifv \$\endgroup\$
    – DyingIsFun
    Commented Sep 23, 2023 at 20:54
  • \$\begingroup\$ The only solution that worked for me was Kinematic Rigidbody2D with raycasts in the 4 directions (3 rays in each direction was enough). Then control directly velocity based on input, wall collisions based on rays and trigger collider for damage. With rays you can slightly "cross" them at the "edges" of the character to make it handle slopes better yet there is no slipping off platforms edges like with a capsule. This crossings of rays can even be used so determine to what angle slopes can be climbed. \$\endgroup\$
    – Nikaas
    Commented Oct 3, 2023 at 8:44

1 Answer 1

0
+250
\$\begingroup\$

I recently came across this video about stair traversal in videogames, and I liked the way the solution looked. I think the main way it differs from your most recent attempt is that it only snaps straight up or down, giving that box-like feeling you're after.

On the way up stairs and ramps, you use a collision check to implement the snapping. To go down, you use a raycast. You'll have to skip a raycast each jump (so you can actually jump without getting immediately snapped down), and disable them until landing when you detect a frame in which the character isn't on the ground or being snapped to it (so you don't get snapped down just before landing from a long fall or just after jumping).

I don't forsee the noisy sloped ground case being terribly problematic unless it's so noisy that the player gets vibrated up and down, but perhaps the collision mesh would be the more appropriate thing to adjust there.

You should probably save the bounty for the industry veteran that you specifically requested, but I figured it couldn't hurt to give you another thing to try along with a demo.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .