Skip to content
Snippets Groups Projects
Select Git revision
  • 36fc63f5aff20c5be5a0547d29ccf56ac32307a1
  • main default protected
2 results

FirstPersonCharacterController.cs

Blame
  • FirstPersonCharacterController.cs 8.54 KiB
    using UnityEngine;
    using UnityEngine.InputSystem;
    using Weapons;
    
    namespace Player.FirstPersonController
    {
        public class FirstPersonCharacterController : MonoBehaviour
        {
            // Contrôles
            [Header("Contrôles")]
            private PlayerInput _playerInput;
            private InputAction _moveAction;
            private InputAction _lookAction;
            private InputAction _runAction;
            private InputAction _jumpAction;
            private InputAction _crouchAction;
            private InputAction _interactAction;
            private InputAction _shootAction;
            private InputAction _reloadAction;
            private InputAction _changeWeaponAction;
            private Vector2 _movementAxis;
            private Vector2 _lookAxis;
            private bool _runningBtn;
            private float _playerControllForce;
            [SerializeField] private float controllerDeadZone = 0.1f;
            [SerializeField] private bool lockCursor = true;
            [SerializeField] private float lookSensitivity = 2f;
            [SerializeField] private int verticalLookSign = 1;
            [SerializeField] private int horizontalLookSign = 1;
        
            // Physique
            [Header("Physique")]
            private Vector3 _velocity;
    
            [SerializeField] private float gravity = -9.81f;
    
            // Mouvement
            [Header("Mouvement")]
            [SerializeField] private float walkSpeed = 6f;
            [SerializeField] private float runSpeed = 10f;
            [SerializeField] private float crouchSpeed = 3f;
            [SerializeField] private float jumpHeight = 1.5f;
    
            // Ground Checks
            [Header("Ground Checks")]
            [SerializeField] private bool isGrounded;
            [SerializeField] private float groundCheckDistance = 0.17f;
            [SerializeField] private LayerMask groundMask;
        
            // Références
            private CharacterController _controller;
            private GameObject _camera;
            private Vector3 _cameraForward;
            private Vector3 _cameraRight;
            private Quaternion _rotation;
            private Weapon[] _weapons;
            private int _currentWeaponIndex;
    
            //Awake is called when the script instance is being loaded.
            void Awake()
            {
                _playerInput = GetComponent<PlayerInput>();
                _moveAction = _playerInput.currentActionMap.FindAction("Move");
                _moveAction.performed += ctx => _movementAxis = ctx.ReadValue<Vector2>();
                _moveAction.canceled += _ => _movementAxis = Vector2.zero;
            
                _lookAction = _playerInput.currentActionMap.FindAction("Look");
                _lookAction.performed += ctx => _lookAxis = ctx.ReadValue<Vector2>();
                _lookAction.canceled += _ => _lookAxis = Vector2.zero;
            
                _runAction = _playerInput.currentActionMap.FindAction("Run");
                _runAction.started += _ => _runningBtn = true;
                _runAction.canceled += _ => _runningBtn = false;
            
                _jumpAction = _playerInput.currentActionMap.FindAction("Jump");
                _jumpAction.started += _ => Jump();
            
                _crouchAction = _playerInput.currentActionMap.FindAction("Crouch");
                _crouchAction.started += _ => Crouch();
            
                _interactAction = _playerInput.currentActionMap.FindAction("Interact");
                _interactAction.started += _ => Interact();
                
                // Weapons
                _shootAction = _playerInput.currentActionMap.FindAction("Shoot");
                _shootAction.started += _ => Shoot();
                
                _reloadAction = _playerInput.currentActionMap.FindAction("Reload");
                _reloadAction.started += _ => Reload();
                
                _changeWeaponAction = _playerInput.currentActionMap.FindAction("Change Weapon");
                _changeWeaponAction.started += ctx => ChangeWeapon(ctx.ReadValue<int>());
            }
        
            // Start is called before the first frame update
            void Start()
            {
                for (int i = 0; i < Gamepad.all.Count; i++)
                {
                    Debug.Log(Gamepad.all[i].name);
                }
            
                _controller = GetComponent<CharacterController>();
                _camera = GameObject.Find("Player Camera");
            
                _rotation = transform.rotation;
                
                GameObject weaponsContainer = GameObject.Find("Weapons");
                _weapons = weaponsContainer.GetComponentsInChildren<Weapon>();
                for (int i = 0; i < _weapons.Length; i++)
                {
                    if(i>0)
                        _weapons[i].gameObject.SetActive(false);
                }
                _currentWeaponIndex = 0;
            }
    
            // Update is called once per frame
            void Update()
            {
                Move();
                _playerControllForce = Mathf.Clamp(Mathf.Abs(_movementAxis.y)+Mathf.Abs(_movementAxis.x), 0, 1);
            }
    
            private void LateUpdate()
            {
                Look();
            }
    
            void OnDrawGizmosSelected()
            {
                // Dessine une boule rouge pour visualier goundCheckDistance
                Gizmos.color = Color.red;
                Gizmos.DrawSphere(transform.position, groundCheckDistance);
            }
    
            void Move()
            {
                // Récupère les vecteurs de la caméra
                _cameraForward = _camera.transform.forward;
                _cameraRight = _camera.transform.right;
     
                // On les normalises (0-1)
                _cameraForward.Normalize();
                _cameraRight.Normalize();
            
                isGrounded = Physics.CheckSphere(transform.position, groundCheckDistance, groundMask);
    
                if (isGrounded)
                {
                    if (_velocity.y < 0)
                    {
                        _velocity.y = 0f;
                    }
                
                    if(_playerControllForce > controllerDeadZone){
                        if(_runningBtn){
                            // Run
                            Run();
                        }else{
                            // Walk
                            Walk();
                        }
                    } else {
                        // Idle
                        Idle();
                    }
                }
            
                _velocity.y += gravity * Time.deltaTime; // Calcul de la gravité
                _controller.Move(_velocity * Time.deltaTime); // Application de la gravité
                transform.rotation = _rotation; // Rotation
            }
        
            private void Jump(){
                if (isGrounded)
                {
                    _velocity.y = Mathf.Sqrt(jumpHeight * -3.0f * gravity);
                }
            }
    
            private void Look()
            {
                // Cursors
                Cursor.lockState = lockCursor? CursorLockMode.Locked: CursorLockMode.None;
                Cursor.visible = lockCursor? false: true;
            
                _rotation *= Quaternion.Euler(0, _lookAxis.x * horizontalLookSign * lookSensitivity * Time.deltaTime, 0);
                _camera.transform.Rotate(_lookAxis.y * (-1) * verticalLookSign * lookSensitivity * Time.deltaTime, 0, 0);
            }
        
            private void Walk()
            {
                float verticalVelocity = _velocity.y;
            
                _velocity = _cameraForward * (_movementAxis.y * walkSpeed) + _cameraRight * (_movementAxis.x * walkSpeed);
                _velocity.y = verticalVelocity;
            }
        
            private void Run()
            {
                float verticalVelocity = _velocity.y;
            
                _velocity = _cameraForward * (_movementAxis.y * runSpeed) + _cameraRight * (_movementAxis.x * runSpeed);
                _velocity.y = verticalVelocity;
            }
        
            private void Idle()
            {
                _velocity.x = 0f;
                _velocity.z = 0f;
            }
        
            private void Crouch()
            {
                _velocity.x = _movementAxis.x * crouchSpeed;
                _velocity.z = _movementAxis.y * crouchSpeed;
            }
        
            private void Interact()
            {
                Debug.Log("Interact");
            }
            
            // Weapon
            private void ChangeWeapon(int buttonValue)
            {
                int index;
                if(buttonValue == 1)
                    index = _currentWeaponIndex + 1;
                else
                    index = _currentWeaponIndex - 1;
    
                if(index < 0)
                    index = _weapons.Length - 1;
                else if(index >= _weapons.Length)
                    index = 0;
                
                _weapons[_currentWeaponIndex].gameObject.SetActive(false);
                _currentWeaponIndex = index;
                _weapons[_currentWeaponIndex].gameObject.SetActive(true);
            }
            
            private void Shoot()
            {
                _weapons[_currentWeaponIndex].Shoot();
            }
            
            private void Reload()
            {
                _weapons[_currentWeaponIndex].Reload();
            }
        }
    }