így jó?

mail@pastecode.io avatar
unknown
csharp
a year ago
6.6 kB
7
Indexable
Never
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FirstPersonController : MonoBehaviour
{
    public bool CanMove { get; private set; } = true;
    //private bool isSprinting => canSprint && playerControls.Player.Sprint.ReadValue<float>() > 0f;
    private bool ShouldSprint => canSprint && playerControls.Player.Move.ReadValue<Vector2>().y > 0.5f;
    private bool ShouldJump => playerControls.Player.Jump.ReadValue<float>() > 0f && characterController.isGrounded;
    private bool ShouldCrouch => playerControls.Player.Crouch.ReadValue<float>() > 0f && !duringCrouchAnimation;

    [Header("Function Options")]
    [SerializeField] private bool canSprint = true;
    [SerializeField] private bool canJump = true;
    [SerializeField] private bool canCrouch = true;

    [Header("Movement Parameters")]
    [SerializeField] private float walkSpeed = 5f;
    [SerializeField] private float sprintSpeed = 10f;
    [SerializeField] private float crouchSpeed = 3f;

    [Header("Look Parameters")]
    [SerializeField, Range(1, 10)] private float lookSpeedX = 2f;
    [SerializeField, Range(1, 10)] private float lookSpeedY = 2f;
    [SerializeField, Range(1, 180)] private float upperLookLimit = 80f;
    [SerializeField, Range(1, 180)] private float lowerlookLimit = 80f;

    [Header("Jumping Parameters")] //Space
    [SerializeField] private float jumpForce = 8f;
    [SerializeField] private float gravity = 30f;

    [Header("Sprint Parameters")] //Auto
    [SerializeField] private float timeToSprint = 2f;
    private float targetSpeed;
    private bool isSprinting;

    [Header("Crouch Parameters")] //C
    [SerializeField] private float crouchHeight = 1f;
    [SerializeField] private float standingHeight = 2f;
    [SerializeField] private float timeToCrouch = 0.25f;
    [SerializeField] private Vector3 crouchingCenter = new Vector3(0, 0.5f, 0);
    [SerializeField] private Vector3 standingCenter = new Vector3(0, 0, 0);
    private bool isCrouching;
    private bool duringCrouchAnimation;

    private Camera playerCamera;
    private CharacterController characterController;
    private PlayerControls playerControls;

    private Vector3 moveDirection;
    private Vector2 currentInput;

    private float rotationX = 0;

    private void Awake()
    {
        playerCamera = GetComponentInChildren<Camera>();
        characterController = GetComponent<CharacterController>();
        playerControls = new PlayerControls();
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    private void Update()
    {
        if (CanMove)
        {
            HandleMovementInput();
            HandleMouseLook();

            if (canJump)
                HandleJump();
            if (canCrouch)
                HandleCrouch();
            if (canSprint)
                HandleSprint();

            ApplyFinalMovements();
        }
    }

    private void HandleMovementInput()
    {
        currentInput = new Vector2((isCrouching ? crouchSpeed : isSprinting ? sprintSpeed : walkSpeed) * playerControls.Player.Move.ReadValue<Vector2>().y, (isCrouching ? crouchSpeed : isSprinting ? sprintSpeed : walkSpeed) * playerControls.Player.Move.ReadValue<Vector2>().x);
        Debug.Log(playerControls.Player.Move.ReadValue<Vector2>());
        float moveDirectionY = moveDirection.y;
        moveDirection = (transform.TransformDirection(Vector3.forward) * currentInput.x) + (transform.TransformDirection(Vector3.right) * currentInput.y);
        moveDirection.y = moveDirectionY;
    }

    private void HandleMouseLook()
    {
        rotationX -= playerControls.Player.Look.ReadValue<Vector2>().y * (lookSpeedY/10f);
        rotationX = Mathf.Clamp(rotationX, -upperLookLimit, lowerlookLimit);
        playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
        transform.rotation *= Quaternion.Euler(0, playerControls.Player.Look.ReadValue<Vector2>().x * (lookSpeedX/10f), 0);
    }
    private void HandleJump()
    {
        if (ShouldJump)
            moveDirection.y = jumpForce;
    }

    private void HandleCrouch()
    {
        if (ShouldCrouch)
            StartCoroutine(CrouchStand());
    }

    private void HandleSprint()
    {
        if (ShouldSprint)
            StartCoroutine(SprintAuto());
        else
            isSprinting = false;
            sprintSpeed = targetSpeed;
    }

    private void ApplyFinalMovements()
    {
        if (!characterController.isGrounded)
        {
            moveDirection.y -= gravity * Time.deltaTime;
        }

        characterController.Move(moveDirection * Time.deltaTime);
    }

    private IEnumerator CrouchStand()
    {
        if (isCrouching && Physics.Raycast(playerCamera.transform.position, Vector3.up, 1f))
            yield break;

        duringCrouchAnimation = true;

        float timeElapsed = 0f;
        float targetHeight = isCrouching ? standingHeight : crouchHeight;
        float currentHeight = characterController.height;
        Vector3 targetCenter = isCrouching ? standingCenter : crouchingCenter;
        Vector3 currentCenter = characterController.center;

        while(timeElapsed < timeToCrouch)
        {
            characterController.height = Mathf.Lerp(currentHeight, targetHeight, timeElapsed / timeToCrouch);
            characterController.center = Vector3.Lerp(currentCenter, targetCenter, timeElapsed / timeToCrouch);
            timeElapsed += Time.deltaTime;
            yield return null;
        }

        characterController.height = targetHeight;
        characterController.center = targetCenter;

        isCrouching = !isCrouching;

        duringCrouchAnimation = false;
    }

    private IEnumerator SprintAuto()
    {
        float timeElapsed = 0f;
        targetSpeed = sprintSpeed;
        Debug.Log("sprintespeed:" +sprintSpeed);
        float currentSpeed = isSprinting ? targetSpeed : walkSpeed;

        isSprinting = true;

        while (timeElapsed < timeToSprint)
        {
            sprintSpeed = Mathf.Lerp(currentSpeed, targetSpeed, timeElapsed / timeToSprint);
            timeElapsed += Time.deltaTime;
            yield return null;
            //Debug.Log(sprintSpeed);
            //Debug.Log(sprintSpeed);
        }




        //if (timeElapsed > timeToSprint)
        //{
        //    isSprinting = true;
        //    Debug.Log(isSprinting);
        //}

        //Debug.Log(isSprinting);
    }

    private void OnEnable()
    {
        playerControls.Enable();
    }

    private void OnDisable()
    {
        playerControls.Disable();
    }
}