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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

My FPS Character controller

Discussion in 'Scripting' started by daniel-spain, Mar 31, 2016.

  1. daniel-spain

    daniel-spain

    Joined:
    Mar 31, 2016
    Posts:
    1
    Greetings everyone, i am new here, and have been tinkering around for a while and decided to make my own FPS the kids can run around in shooting things.
    Now i am simply a hobbyist, i do this for fun and my code may be off, may even be wrong, so please if you see something unconventional or simply backwards feel free to let me know.
    I have been writing online text role-playing games for years in C and Unity is completely new to me and i am a little out of my comfort zone so i figured i would post my player controller here, explain what i am trying to do, and take the feedback and run with it.

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. var horizontalSensitivity = 2.0;
    5. var invertAxis = true;
    6. var verticalSensitivity = 2.0;
    7. var minVerticalRange = -65.0;
    8. var maxVerticalRange = 65.0;
    9. var forwardSpeed = 5.0;
    10. var runMultiplier = 2.0;
    11. var backwardSpeed = 1.75;
    12. var crouchSpeed = 0.5;
    13. var strafeSpeed = 1.25;
    14. var jumpSpeed = 5.0;
    15.  
    16. private var horizontalRotation : float;
    17. private var verticalRotation : float;
    18. private var cursorIsLocked : boolean;
    19. private var isGrounded : boolean;
    20. private var characterController : CharacterController;
    21. private var isJumping : boolean;
    22. private var verticalVelocity : float;
    23. private var isCrouching : boolean;
    24. private var verticalSpeed : float;
    25. //private var playerStats : PlayerStats;
    26. private var speedMod : float;
    27. private var horizontalSpeed : float;
    28. private var playerSpeed : Vector3;
    29.  
    30. static var fallTime : float;
    31. static var isFalling : boolean;
    32. static var canRegen : boolean;
    33. static var isRunning : boolean;
    34.  
    35. function Start()
    36. {
    37.     verticalRotation = 0;
    38.     cursorIsLocked = true;
    39.     characterController = GetComponent(CharacterController);
    40.     isGrounded = true;
    41.     isCrouching = false;
    42.     isJumping = false;
    43.     isRunning = false;
    44.     isFalling = false;
    45.     //playerStats = GetComponent(PlayerStats);
    46. }
    47.  
    48. function Update()
    49. {
    50.     if(Input.GetKeyUp(KeyCode.Escape))
    51.     {
    52.         cursorIsLocked = !cursorIsLocked;
    53.     }
    54.  
    55.     if(cursorIsLocked)
    56.     {
    57.         Cursor.lockState = CursorLockMode.Locked;
    58.         Cursor.visible = false;
    59.     }
    60.      
    61.     if(!cursorIsLocked)
    62.     {
    63.         Cursor.lockState = CursorLockMode.None;
    64.         Cursor.visible = true;
    65.     }
    66.  
    67.     horizontalRotation = Input.GetAxis("Mouse X") * horizontalSensitivity;
    68.     transform.Rotate (0, horizontalRotation, 0);
    69.  
    70.     if(invertAxis)
    71.     {
    72.         verticalRotation -= Input.GetAxis("Mouse Y") * verticalSensitivity;
    73.     }
    74.     else
    75.     {
    76.         verticalRotation += Input.GetAxis("Mouse Y") * verticalSensitivity;
    77.     }
    78.  
    79.     verticalRotation = Mathf.Clamp(verticalRotation, minVerticalRange, maxVerticalRange);
    80.  
    81.     Camera.main.transform.localRotation = Quaternion.Euler(verticalRotation, 0, 0);
    82.  
    83.     isGrounded = characterController.isGrounded;
    84.  
    85.     if(isGrounded)
    86.     {
    87.         isJumping = false;
    88.         verticalVelocity = 0;
    89.         fallTime = 0;
    90.         isFalling = false;
    91.     }
    92.  
    93.     if(isGrounded && Input.GetKeyUp(KeyCode.LeftControl))
    94.     {
    95.         isCrouching = !isCrouching;
    96.     }
    97.  
    98.     isJumping = false;
    99.  
    100.     if(isGrounded && Input.GetButtonDown("Jump"))
    101.     {
    102.         if(isCrouching)
    103.         {
    104.             isCrouching = false;
    105.         }
    106.         else
    107.         {
    108.             isJumping = true;
    109.            //isCrouching = false;
    110.         }
    111.     }
    112.  
    113.     verticalSpeed = Input.GetAxis("Vertical");
    114.  
    115.     canRegen = true;
    116.     isRunning = false;
    117.  
    118.     if(Input.GetKey(KeyCode.LeftShift) && verticalSpeed != 0)
    119.     {
    120.         isRunning = true;
    121.         canRegen = false;
    122.         isCrouching = false;
    123.     }
    124.  
    125.     /*if(playerStats.currentRunStamina < 1.0)
    126.     {
    127.         isRunning = false;
    128.     }*/
    129.  
    130.     if(verticalSpeed > 0)
    131.     {
    132.         if(isRunning)
    133.         {
    134.             speedMod = forwardSpeed * runMultiplier;
    135.         }
    136.         else
    137.         {
    138.             speedMod = forwardSpeed;
    139.         }
    140.     }
    141.     else
    142.     {
    143.         speedMod = backwardSpeed;
    144.     }
    145.  
    146.     if(isCrouching)
    147.     {
    148.         speedMod = crouchSpeed;
    149.     }
    150.  
    151.     verticalSpeed *= speedMod;
    152.  
    153.     if(!isGrounded)
    154.     {
    155.         horizontalSpeed = 0;
    156.     }
    157.     else
    158.     {
    159.         horizontalSpeed = Input.GetAxis ("Horizontal") * strafeSpeed;
    160.     }
    161.  
    162.     verticalVelocity += Physics.gravity.y * Time.deltaTime;
    163.  
    164.     if(isJumping)
    165.     {
    166.         verticalVelocity = jumpSpeed;
    167.     }
    168.  
    169.     playerSpeed = Vector3(horizontalSpeed, verticalVelocity, verticalSpeed);
    170.     playerSpeed = transform.rotation * playerSpeed;
    171.  
    172.     characterController.Move(playerSpeed * Time.deltaTime);
    173.  
    174.     if(isCrouching)
    175.     {
    176.         Camera.main.transform.localPosition.y = 0.5;
    177.         characterController.height = 0.5;
    178.     }
    179.     else
    180.     {
    181.         Camera.main.transform.localPosition.y = 1.0;
    182.         characterController.height = 2.0;
    183.     }
    184. }
    185.  
    186.  
    187. function FixedUpdate()
    188. {
    189.     if(transform.localPosition.y < 0.0)
    190.     {
    191.         isFalling = true;
    192.         fallTime += Time.fixedDeltaTime;
    193.     }
    194.     else
    195.     {
    196.         isFalling = false;
    197.     }
    198.  
    199.     if(isFalling && fallTime >= 5.0)
    200.     {
    201.         transform.localPosition.x = 0;
    202.         transform.localPosition.y = 0;
    203.         transform.localPosition.z = 0;
    204.         fallTime = 0;
    205.         isFalling = false;
    206.     }
    207. }
    208.  
    From a simple approach is works, i can walk, run, strafe, crouch, jump, and handle falling.
    From a more complex approach i want to handle crouching a little better as its really rough, so maybe smooth it out a bit? And also i have read various arguments about using Update vs FixedUpdate and i would love some clarification, someone told me to put the mouse movement stuff in update, but process the GetButton handlers in Fixed, Am i going at this all wrong? Or am i heading in the right direction with this script?
    The game i want to use basic functionality such as Walking, Running, Jumping, Crouching, and Strafing, i will handle other things later once i am satisfied with my player controller.

    When i use this script, i simple use a GameObject i call Player, attach a CharacterController component to it, and this script along with a PlayerStats script which just handles health, stamina, etc.... i removed those components for now to make sure i am heading in the right direction.

    Any help would be great.

    thanks......

    Daniel
     
  2. HAlbera

    HAlbera

    Joined:
    Jun 7, 2013
    Posts:
    63
    Well I'm not the most experienced programmer, but it looks alright to me!

    There's one in the standard assets that come with unity, so when you think you've got it sussed, go see how they did it?

    Your code looks tidy so grats :)

    EDIT: from my experience, whenever ive put keyboard or mouse stuff in fixed update its been temperamental. I always put it in regular update now. No idea about the implications of that though.