Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Character Controller, and small ledges (steps, if you will)

Discussion in 'Scripting' started by Warrior1424, Oct 30, 2014.

  1. Warrior1424

    Warrior1424

    Joined:
    Sep 30, 2010
    Posts:
    984
    Here is my question:
    How would one program it so that a character may go up a small ledge (like a step), but also reacts to slopes appropriately?

    Now I know what you're thinking,
    "Just use a ramp for the collider!"
    The question isn't how to make it so that a player may ascend stairs, but how to make it so that the player can "step" up onto small ledges.
    You can't just add a little ramp collider every time you have a small ledge somewhere on your level.
    You also can't make the maxAngle of the Controller to 90, because then you can run straight up any slope.
    I tried making a separate script to handle sliding, but no matter how I approached it I couldn't get it to work in every possible situation.

    This question has been asked so many times before, but never has a real solution been found (at least not publicly, or at least I haven't seen it).

    This has been done in many other games, so why can't anyone seem to get it right in Unity?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    So you don't like the results that you get from CharacterController.stepOffset?

    Ok...

    How about you set the stepOffset lower than the ledge. So you'll now have a second value, a 'ledgeOffest'. As long as stepOffset is lower than the ledgeOffset, than the CharacterController.Move call will stop when you hit a ledge.

    Now, after you've called Move, and if the Move returns that you've hit a wall (check the CollisionFlags returned by Move). Then from the point just in front of the CharacterController, Raycast downward, and if you hit the ground, check the vertical distance between that point at the position of the CharacterController. If it's less than 'ledgeOffset', this is a ledge. Move the player up onto the ledge (play animation, do other stuff).
     
  3. Warrior1424

    Warrior1424

    Joined:
    Sep 30, 2010
    Posts:
    984
    So then how would you "move" the player onto the ledge?
    Would you just move them up by a certain amount, and then push them forward by a bit?
    And how would you know how far to push them?
    And what if the player came in at an angle towards the step? They would have to be pushed more than if they went in head-on.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Sure. If that's what is expected.

    If you hit the wall you didn't move the full horizontal distance the call to Move passed in. So you know how much you actually moved, and how much you wanted to move, so you can move 'forward' the rest of the amount you desired.

    Again, you just called Move, you have the vector that you wanted to move by. Store the last position before you call Move, then substract that from the resulting position, that's the total ACTUAL change. You now know how much you did change, and how much you wanted to change.

    Code (csharp):
    1.  
    2. Vector3 mv = *the amount we expect to move*;
    3. var lastPos = controller.transform.position;
    4. var flags = controller.Move(mv);
    5. if(flags & CollisionFlags.Sides != 0)
    6. {
    7.     //we hit something on our sides
    8.     var realMv = controller.transform.position - lastPos; //this is the amount that we ACTUALLY moved when calling Move
    9.    
    10.     //TODO - do raycast test, if hit, do stuff
    11. }
    12.  
     
  5. Warrior1424

    Warrior1424

    Joined:
    Sep 30, 2010
    Posts:
    984
    If I was standing directly next to the step, and tapped the "W" key, what would happen?
    I would be pushed up, and pushed forward by the amount I was moving before I hit the wall, right?
    What if that amount isn't enough to fully get the controller onto the ledge, and the curved part at the bottom

    got stuck on the edge of the ledge?
    Wouldn't it slide back down off the ledge?
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    A lot could happen.

    You have to write the code to decide WHAT happens.
     
  7. Warrior1424

    Warrior1424

    Joined:
    Sep 30, 2010
    Posts:
    984
    Wait, what?

    "A lot could happen."
    Do you mean a lot of problems could arise in your solution, making it not much of a solution after all? Or a lot of problems could happen when attempting to make the player step up onto ledges?

    "You have to write the code to decide WHAT happens."
    So I have to write the code that decides what problems happen?
    Or is this statement not related to the previous one? In that case, I'm fully aware I have to write the code that decides what happens, that's the entire reason I started this thread. I cannot figure out what techniques must be used to accomplish this effect.

    I'm not trying to be mean, I just don't understand what you mean by that post.
     
    noio likes this.
  8. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Nothing happens in my solution if you don't do anything.

    I gave you a method to determine IF you're near ledge. Nothing happens from doing that. You just know you're next to a ledge.

    YOU need to decide what to do from there. Because I don't know what you want to happen once you determined there is a ledge.

    I'm not going to code up your solution for you. I gave you a direction to go. Go test it, play with it, see what you can do with it.
     
    bouloublue and noio like this.