Newer
Older
HierarchicalFSM-Unity3D / Assets / Scripts / Player / PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    private Rigidbody rb;
    private Vector2 currentVelocity;
    private Vector2 targetVelocity;
    private Animator animator;

    [SerializeField] private bool crouch = false;
    [SerializeField] private bool canCrouchCover = false;

    [SerializeField] private float rotationSpeed = 5f;
    [SerializeField] private float movementSmoothing = 0.1f; // Adjust this value to control smoothing
    public float smoothing = 0.1f; // Adjust this value to control smoothing

    private float currentTurnValue;
    private float turnVelocity;

    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
        animator = GetComponent<Animator>();
    }

    // Start is called before the first frame update
    void Start()
    {
        animator.applyRootMotion = true;
    }

    // Update is called once per frame
    void Update()
    {
        IsCrouched();
        ApplyRotation();
        // Read input values once per frame
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        // Determine velocity based on whether the player is running
        if (IsRunning())
        {
            //Apply smothness movement
            targetVelocity = new Vector2(horizontal, vertical) * 2f;
        }
        else
        {
            //Apply smothness movement
            targetVelocity = new Vector2(horizontal, vertical);
        }

        // Smoothly interpolate the current velocity towards the target velocity
        currentVelocity = Vector2.Lerp(currentVelocity, targetVelocity, movementSmoothing);

        // Update animator parameters
        animator.SetFloat("Horizontal", currentVelocity.x);
        animator.SetFloat("Vertical", currentVelocity.y);

        // Debug logs
        //Debug.Log("IsRunning: " + IsRunning());
        //Debug.Log("Horizontal: " + velocity.x);
        //Debug.Log("Vertical: " + velocity.y);

        animator.SetBool("Crouched", crouch);
        animator.SetBool("CrouchCover", canCrouchCover);
    }

    //Checks if the player is running
    private bool IsRunning() => Input.GetKey(KeyCode.LeftShift) ? true : false;


    private void IsCrouched()
    {
        if (Input.GetKeyDown(KeyCode.LeftControl))
        {
            crouch = !crouch;
        }
    }

    void OnCollisionStay(Collision collision)
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            Debug.Log("COLLISION!");
            foreach (ContactPoint contact in collision.contacts)
            {
                if (contact.otherCollider.tag == "SmallWall") canCrouchCover = !canCrouchCover;
                break;
            }
        }
    }

    private void OnAnimatorMove()
    {
        Vector3 pos;
        if(canCrouchCover)
        {
            pos = new Vector3(transform.position.x, transform.position.y, animator.rootPosition.z);
            transform.position = pos;
        }
        
        else
        {
            transform.position = animator.rootPosition;
            transform.rotation = animator.rootRotation;
        }
    }

    void RotateCharacter(float turnValue)
    {
        // Set the Turn parameter in the animator
        animator.SetFloat("Turn", turnValue);

        // Apply the rotation to the character
        transform.Rotate(Vector3.up, turnValue * rotationSpeed * Time.deltaTime);
    }

    void ApplyRotation()
    {
        // Get mouse input
        float mouseX = Input.GetAxis("Mouse X");

        // Smooth the input
        float targetTurnValue = mouseX;

        // Smoothly interpolate the turn value
        currentTurnValue = Mathf.Lerp(currentTurnValue, targetTurnValue, smoothing);

        // Rotate the character based on the smoothed input
        if (mouseX != 0)
        {
            RotateCharacter(currentTurnValue);
        }
        else
        {
            // Smoothly reset the Turn parameter to 0 when there is no rotation input
            currentTurnValue = Mathf.Lerp(currentTurnValue, 0, smoothing);
            animator.SetFloat("Turn", currentTurnValue);
        }
    }
}