FreshRSS

Normální zobrazení

Jsou dostupné nové články, klikněte pro obnovení stránky.
PředevčíremHlavní kanál

Character controller that can handle sloped terrain and boxy ledge traversal

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?

  • ✇Recent Questions - Game Development Stack Exchange
  • How to stop the slide on slopes?Sam Law
    I'm struggling with a wee issue where if my character walks up a slope he slides back down when at rest, and bounces down when running down the slope. I've followed a few videos but none seem to address the issue. I've posted my movement code so far and I'm not opposed to fundamentally changing this, however with the other aspects of my game, the rigid body and collider setup seems to be working quite well. Any ideas? //inputs if (Input.GetKey(buttonKey["Left"])) { inputHorizont
     

How to stop the slide on slopes?

I'm struggling with a wee issue where if my character walks up a slope he slides back down when at rest, and bounces down when running down the slope. I've followed a few videos but none seem to address the issue. I've posted my movement code so far and I'm not opposed to fundamentally changing this, however with the other aspects of my game, the rigid body and collider setup seems to be working quite well. Any ideas?

 //inputs
    if (Input.GetKey(buttonKey["Left"]))
    {
        inputHorizontal = -1;
    }
    else if (Input.GetKey(buttonKey["Right"]))
    {
        inputHorizontal = 1;
    }
    else
    {
        inputHorizontal = 0;
    }

    //jump
    if (Input.GetKey(buttonKey["Jump"]) && isgrounded.Grounded && canJump)
    {
        jump();
        jumpTimerCurrent = 0;
        canJump = false;
    }

    if (jumpTimerCurrent <= jumpTimerReset)
    {
        jumpTimerCurrent += Time.fixedDeltaTime;
    }
    else
    {
        canJump = true;
    }

 void FixedUpdate()
{
    rb.velocity = new Vector2(inputHorizontal * Time.fixedDeltaTime * runSpeed, rb.velocity.y);
}

    void jump()
{
    rb.velocity = new Vector2(rb.velocity.x, 0.0f);
    rb.AddForce(Vector2.up * jumpForce, ForceMode.Force);
}
❌
❌