Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Player getting stuck on the edges of every object?

Discussion in 'Scripting' started by androidac67, Sep 21, 2023.

  1. androidac67

    androidac67

    Joined:
    Jan 3, 2023
    Posts:
    75
    I have a standard character controller with no other colliders attached to my player but when I jump onto the very edge of any kind of object (cube, sphere, custom pyramid/cone), my player gets stuck even though the isGrounded bool is false in the photo. I get that a very tiny bit of the cylinder is still touching the other object, but the game says here that my player is not grounded, and I have code specifically to push the player downwards when not grounded using
    velocity.y
    so I do not understand this. What should happen in the photo is my player should fall down, not stay glued to the tall brown rectangular object on the left.


    I have spent the last month entirely focused on this and I have followed many tutorials including using code from so many threads on this forum and elsewhere but this problem exists everywhere, even in several free assets that I downloaded and tested from the official store so at this point I don't know if it's just me and I should ignore this.

    I tested the standard
    controller.isGrounded
    ,
    Physics.Raycast
    ,
    Physics.BoxCast
    ,
    Physics.SphereCast
    ,
    Physics.CheckSphere
    and I used gizmos to visualize all of them to make sure I had the correct origin position & radius of all of them, etc, but the problem still persists. I have tried altering my own code to make sure that
    .Move()
    was only being called once rather than twice in
    Update
    which has not helped at all and I have tested the controller settings
    Skin Width
    ,
    Min Move Distance
    ,
    Step Offset
    and even
    Slope Limit
    but there's no difference. I have used both a Capsule and Cylinder as my player and tried different scales which also didn't fix the problem. I have adjusted the gravity value and also tried using
    velocity.y
    in different parts of my code (such as outside of my isGrounded bool). There's much more that I've tried but basically I'm still stuck at the start.

    My current code is intentionally very simple in hopes that if I find the solution I can quickly pinpoint what the issue was. In this code I am calling .Move() twice but it's not causing the issue (I believe) so I just kept it in there.

    Code (CSharp):
    1. public Transform groundCheck;
    2. public float groundDistance = 0.4f;
    3. public LayerMask groundMask;
    4.  
    5. void Update()
    6. {
    7.     isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    8.  
    9.     if (isGrounded && velocity.y < 0)
    10.     {
    11.         velocity.y = -2f;
    12.     }
    13.  
    14.     float x = Input.GetAxis("Horizontal");
    15.     float z = Input.GetAxis("Vertical");
    16.  
    17.     Vector3 move = transform.right * x + transform.forward * z;
    18.  
    19.     controller.Move(move * speed * Time.deltaTime);
    20.  
    21.     if (Input.GetButtonDown("Jump") && isGrounded)
    22.     {
    23.         velocity.y = Mathf.Sqrt(jump * -2f * gravity);
    24.     }
    25.    
    26.     velocity.y += gravity * Time.deltaTime;
    27.  
    28.     controller.Move(velocity * Time.deltaTime);
    29. }
     
    Last edited: Sep 21, 2023
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    It would help to see the collider wireframes in the image above.

    If for instance the cube to the left is subdivided into smaller box colliders stacked on top of each other then it could be the common issue where a collider stops at the edge of another collider even if both colliders align perfectly. I think you can quickly simulate this issue by creating a floor of cubes, each with a box colliders, and then try to walk over these with an object that also uses a box collider. Occassionally, you'll get stuck at a collider edge.

    This is one reason why character controllers use capsule colliders as they will smooth over those edges.

    If however the box to the left is just a single box collider (and not a mesh collider either) then this must be a bug in the scripts you are using.

    My best guess is that velocity.y equals 0 since there is no code that handles this special case. You only force a negative velocity if velocity.y is negative. Perhaps something keeps the object with a velocity.y of exactly zero?

    Did you try logging the velocity value?

    I'd definitely revert to a capsule collider as it will avoid issues with collision handling.
    I'd also refactor the code to call Move() only once because that'll make the code easier, you don't have to work with two separate vectors, and who knows how the controller combines those two moves. It may not just do a simple add.
     
  3. androidac67

    androidac67

    Joined:
    Jan 3, 2023
    Posts:
    75
    I actually did log the velocity value and at the start of runtime the y velocity starts at -2f. When I am idle/stuck like in the photo above, my y velocity decreases rapidly and it went all the way to -700f before I ended runtime (and it would have decreased further), all while
    isGrounded
    is false.

    And do you mean that on top of having my in-built character controller which is attached to my player, I should also attach a capsule collider to my capsule/cylinder object itself? I have tried this multiple times but unfortunately didn't notice any difference.
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    I'm not too familiar with the built-in character controller. I thought it works with a sphere collider by default. If it works without it, that's fine. Shouldn't be the cause of this issue.

    The object does have a rigidbody that is set to kinematic?
    Does the object have children with colliders?
    Are any other scripts running that may alter the position of the object?

    You could create a new empty project and put just your character and the script in there to see if that has the same issues.
     
  5. androidac67

    androidac67

    Joined:
    Jan 3, 2023
    Posts:
    75
    Sorry I should have included all of this in my original post.

    My player does not have a rigidbody, and the other objects also do not have any rigidbodies. I have previously tried attaching a rigidbody to the cube object and testing out different settings like gravity on/off and is kinematic on/off, but there was no change.

    There are no children in any of the cube objects. In the example above it's just a Cube object with a cube mesh filter, mesh renderer and default box collider (with no Physic Material). I have also tried changing the cube objects layer from Default to Ground to see if there was any change, but that didn't help.

    I have tested out this exact script and at least half a dozen other scripts on a new, empty project with no other scripts interfering or overlapping and the problem still occurs.

    There's actually a really good script here: https://forum.unity.com/threads/how...racter-movement-in-unity.981939/#post-6379746 but it also has the same issue as my photo when I tested out the Unity package for it.

    My updated player with better detail is here with the picture on the left showing my character controller settings and the right showing my
    GroundCheck
    transform (from my new, empty test project),
    isGrounded
    is false in both photos:

    upload_2023-9-21_21-50-9.png
     
    Last edited: Sep 21, 2023
  6. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    Is it getting stuck at a specific location / height? I'm guessing some other script or method may interfere here and (just as an example) prevent it to go lower than 0 on position.y or something.

    @Kurt-Dekker That's your script. Do you have any idea what could go wrong here?
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,560
    Works fine for me. Fresh video I just made. Purple box is instantaneous .isGrounded (see how it flickers) but the yellow word GROUNDED is the dwell-timed lingering grounded.



    That's off the distro package I posted in that other thread, hacked to add the box and the grounded.

    OP: your first script posted above is definitely BROKEN. It calls Move() twice. That's the entire point of my script, which calls Move() precisely once per frame.

    Discard ANY script that calls Move() more than once per frame, unless you want to wrestle with this a while longer.

    Screen Shot 2023-09-21 at 9.33.20 AM.png
     
  8. androidac67

    androidac67

    Joined:
    Jan 3, 2023
    Posts:
    75
    Thanks for taking the time to reply here. In the video the player kind of hangs off the object like so with very minimal collision (the same goes for my character like in my photo above):

    upload_2023-9-22_3-18-21.png

    Is that something to worry about or is it completely normal as long as I remove one of the .Move() calls?
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,560
    Nothing like physics is happening here.

    If you want physics, use a Rigidbody, not a CharacterController.

    Alternately you can reduce the size of the CC so that it doesn't stick.

    Here's a talk about making a cool physics-based character controller.