Search Unity

Custom Character Controller Doesn't Like Inclines

Discussion in 'Scripting' started by Studio_Akiba, Oct 20, 2017.

  1. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    I have a character controller I have cobbled together, and it works relatively well (well enough for what I need) except for when it is parented to another object.

    If the controller is parented under another object and that object is rotated the character starts rotating randomly and violently.

    This is a particular issue as I have a train system which parents the character under itself to prevent the character from being shoved to the back from the velocity, and needs to be able to go up and down inclines without causing this issue, but I am unsure of what is wrong with it, or how to fix it.

    I have been over many different controllers I can find the code for online, and cannot work out what is wrong (mainly due to the others working very differently from mine).

    Can anyone here see what is wrong?
    Code (CSharp):
    1. /*
    2. * ---- Character Controller: Character Movement ----
    3. *
    4. * To Add:
    5. *      Smoother Movement
    6. *      Better Collision w/ Movement
    7. *      Setup as Static to Save Settings
    8. * */
    9.  
    10. using UnityEngine;
    11.  
    12. public class CustomCharacterController : MonoBehaviour
    13. {
    14.  
    15.     public static CustomCharacterController playerController;
    16.  
    17.     public float speed = 6.0f;
    18.     public float jumpSpeed = 8.0f;
    19.     public float gravity = 20.0f;
    20.  
    21.     private Vector3 moveDirection = Vector3.zero;
    22.  
    23.     void Start()
    24.     {
    25.         Cursor.lockState = CursorLockMode.Locked;
    26.     }
    27.  
    28.     public void DontDestroy()
    29.     {
    30.         //DontDestroyOnLoad(transform.gameObject);
    31.     }
    32.  
    33.     void FixedUpdate()
    34.     {
    35.         if (!PlayerControl.playerControl.isPaused)
    36.         {
    37.             if (Input.anyKeyDown)
    38.             {
    39.                 Cursor.lockState = CursorLockMode.Locked;
    40.             }
    41.  
    42.             float translation = Input.GetAxis("Mouse Y")/*cInput.GetAxis("KVertical")*/ * speed;
    43.             float straffe = Input.GetAxis("Mouse X")/*cInput.GetAxis("KHorizontal")*/ * speed;
    44.            
    45.             translation *= Time.deltaTime;
    46.             straffe *= Time.deltaTime;
    47.  
    48.             CharacterController cc = GetComponent<CharacterController>();
    49.  
    50.             Vector3 moveDir = new Vector3(straffe, 0, translation);
    51.             moveDir = transform.TransformDirection(moveDir);
    52.             //rb.MovePosition(transform.position + moveDir);
    53.             //rb.velocity = moveDir * 70;
    54.  
    55.             if(cc.isGrounded)
    56.             {
    57.                 moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
    58.                 moveDirection = transform.TransformDirection(moveDirection);
    59.                 moveDirection *= speed;
    60.             }
    61.  
    62.             if (Input.GetKeyDown(KeyCode.Escape))
    63.             {
    64.                 Cursor.lockState = CursorLockMode.None;
    65.             }
    66.  
    67.             if (Input.GetKeyDown(PlayerControl.playerControl.sprintKey))
    68.             {
    69.                 //speed = 10.0f;
    70.             }
    71.             if (Input.GetKeyUp(PlayerControl.playerControl.sprintKey) || !Input.GetKeyDown(PlayerControl.playerControl.sprintKey))
    72.             {
    73.                 //speed = 6.0f;
    74.             }
    75.             if (Input.GetKeyDown(KeyCode.Space) && cc.isGrounded)
    76.             {
    77.                 moveDirection.y = jumpSpeed;
    78.             }
    79.             moveDirection.y -= gravity * Time.deltaTime;
    80.             cc.Move(moveDirection * Time.deltaTime);
    81.         }
    82.     }
    83. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Rotating randomly and violently might not be your scripting but rather the physics system fighting itself.

    I found that if you have Rigidbodies parented together (like in a ragdoll), you can't have constraints on bodies that are parented to each other, as this causes some kind of solver fighting that quickly becomes unstable.

    You also might possible be able to achieve what you want with FixedJoints between the parts instead of parenting... have you tried that?
     
  3. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    Sorry, forgot to mention this above.

    The character is first-person, there are no multiple pieces with colliders or constraints.

    I have only a cylinder collider, character controller and a camera under it, player-wise.

    The character has no issue with stairs and ramps, the issue only appears when the player is a child under an object which becomes tilted, thus tilting the player as well, which I think the script tries to correct, but cannot.