Select Git revision
FirstPersonCharacterController.cs

Sofiane Lasri authored
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();
}
}
}