Search Unity

Question Altering character controller with code makes my player sink into the ground?

Discussion in 'Scripting' started by AC67_Androi, Mar 19, 2023.

  1. AC67_Androi

    AC67_Androi

    Joined:
    Jan 3, 2023
    Posts:
    90
    I have tried so many variations of code for crouching. Originally I used transform.localScale() which caused so many problems with parenting, etc, so I found a new method.

    But no matter what I do, if I alter my controller.height or center, my character sinks into the ground. This is the latest variation I have with some help from online resources:

    Code (CSharp):
    1. private Vector3 crouchingHeight = new Vector3(0, 0.6f, 0);
    2.     private Vector3 standingHeight = new Vector3(0, 1f, 0);
    3.  
    4. if (Input.GetKey(KeyCode.LeftControl))
    5.             {
    6.                 isCrouching = true;
    7.                 controller.height = Mathf.MoveTowards(controller.height, 1f, .1f);
    8.                 controller.center = Vector3.MoveTowards(controller.center, crouchingHeight, .1f);
    9.             }
    10.             else
    11.             {
    12.                 isCrouching = false;
    13.                 controller.height = Mathf.MoveTowards(controller.height, 2f, .1f);
    14.                 controller.center = Vector3.MoveTowards(controller.center, standingHeight, .1f);
    15.             }
    I cannot figure it out. When I crouch, I sink slightly into the ground and the bottom of my controller hits an invisible (and non-existent) floor. Even after I uncrouch, it stays in the floor.
     
  2. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,043
    Well, if the player has a collider and you set the collider halfway in the ground you will have issues.
    Maybe decouple the camera from the player and only move the camera? And take a look into LocalPosition as well

    There also are many free or open source character controllers you can look into for reference or just use those
     
  3. AC67_Androi

    AC67_Androi

    Joined:
    Jan 3, 2023
    Posts:
    90
    I'm using the in-built character controller (which can be seen in my title and code) and so I don't have a collider attached to my player itself.

    However, I do have a capsule object that is a component of my player object which has a capsule collider attached to itself.

    I have used localPosition but without using localScale it doesn't work right but with localScale there's much bigger issues so I can't really use that.

    Also the few assets I've seen on the unity store all have very buggy crouching code. Do you have any suggestions?
     
  4. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,043
    The character controller still uses a collider under the hood for collision afaik. Just with a lot of extra fluff.
    Why does localPos not work without scale? It seems like you are just taking the wrong path.

    I think most just use localScale:
    https://github.com/B0N3head/unity-fps-movement-controller (has a gif visualizing it)
    https://github.com/Francesco2426/Unity-3D-Character-Controller/blob/main/PlayerController.cs
     
  5. AC67_Androi

    AC67_Androi

    Joined:
    Jan 3, 2023
    Posts:
    90
    This was my previous crouch code:

    Code (CSharp):
    1. if (Input.GetKeyDown(KeyCode.LeftControl))
    2.             {
    3.                 transform.localScale = crouchScale;
    4.                 transform.position = new Vector3(transform.position.x, transform.position.y - 0.5f, transform.position.z);
    5.             }
    6.  
    7.             if (Input.GetKeyUp(KeyCode.LeftControl))
    8.             {
    9.                 transform.localScale = playerScale;
    10.                 transform.position = new Vector3(transform.position.x, transform.position.y + 0.5f, transform.position.z);
    11.             }
    The most notable issue was that when crouching on an object that I was parented to (like a elevator-type object), my player would completely flatten which I'm assuming is due to the localScale line.

    But thanks for taking the time to link those, I believe the first uses rb movement but I'll check them out
     
  6. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,043
    I suggest also posting the original issue in OP. You can simply scale the object childed to the player the other way around to keep scaling proper, or you can move the player position with the movement of the platform without childing at all
     
  7. AC67_Androi

    AC67_Androi

    Joined:
    Jan 3, 2023
    Posts:
    90
    But in order to detect if there's movement below you, wouldn't you need to SetParent and then add code to tell your player what to do whilst a child of the specific object, like a platform moving side to side?

    Without parenting and when I was trying to use a raycast downwards instead, my player didn't seem to want to stick to whatever object it was standing on.
     
  8. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,043
    You don't have to use setparent, you can just read out the position and calculate the difference per frame and move the player that many frames
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    DevDunk likes this.