Untitled

 avatar
unknown
plain_text
10 months ago
9.0 kB
2
Indexable
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class SC_PlayerMovement : MonoBehaviour
{
    enum PlayerState
    {
        onGround,
        falling,
        jumping,
        launching,
        landing,
        readyToLaunch
    }

    [SerializeField] private float terminalVelocity = -18f;
    [SerializeField] PlayerState m_currentState = PlayerState.onGround;
    PlayerState currentState
    {
        get
        {
            return m_currentState;
        }
        set
        {
            if (value == m_currentState)
            {
                return;
            }

            if (m_currentState == PlayerState.onGround)
            {
                m_momentumVelocity = m_currentVelocity;
                m_currentVelocity = Vector3.zero;
            }

            m_currentState = value;
            Debug.Log(m_currentState);

            LaunchVizualizer?.SetActive(m_currentState == PlayerState.readyToLaunch);
            SC_TimeManager.DilateTime(m_currentState == PlayerState.readyToLaunch ? 0.5f : 1f);

            switch (m_currentState)
            {
                case PlayerState.falling:

                    break;
                case PlayerState.onGround:
                    m_momentumVelocity.y = 0f;
                    transform.position = SnapPosition;
                    break;
                case PlayerState.launching:
                    LaunchInCameraDirection();
                    break;                
                case PlayerState.jumping:
                    m_momentumVelocity.y = jumpStrength;
                    break;
                case PlayerState.readyToLaunch:

                    break;
                case PlayerState.landing:

                    break;
            }
        }
    }

    Vector3 lateralVelocity => new Vector3(m_currentVelocity.x, 0, m_currentVelocity.z);

    Vector3 PlayerInput => new Vector3
    {
        x = Input.GetAxisRaw("Horizontal"),
        y = 0f,
        z = Input.GetAxisRaw("Vertical")
    };

    [SerializeField] private float m_headBobStrength = 0.1f;
    [Header("Hidden Movement")]
    [SerializeField] public Vector3 m_currentVelocity;

    public SC_HeadBobController headBob;

    [Header("Movement")]
    public float jumpStrength;
    public float gravityStrength;
    [SerializeField] private float m_slowFactor = 0.9f;
    [SerializeField] float m_launchForce = 25f;
    [SerializeField] Vector3 m_momentumVelocity;
    [SerializeField] Transform m_cameraHolder;

    [Header("Trial Exponetial")]
    [SerializeField] float m_walkSpeed = 5f;
    [SerializeField] float m_runSpeed = 10f;
    [SerializeField] float m_accelFactor = 2.5f;

    [SerializeField][Range(0.0f, 15.0f)] float m_walkLerpFactor = 0.3f;
    [SerializeField][Range(0.0f, 15.0f)] float m_runLerpFactor = 0.3f;
    [SerializeField][Range(0.0f, 35.0f)] float m_momentumDecayFactor = 2f;

    Vector3 TargetVelocity => transform.TransformDirection(PlayerInput) * ((Input.GetKey(KeyCode.LeftShift) ? m_runSpeed : m_walkSpeed));

    [Header("Components")]
    CharacterController m_controller;
    CharacterController Controller
    {
        get
        {
            if (!m_controller) 
                m_controller = GetComponent<CharacterController>();

            return m_controller;
        }
    }

    RaycastHit LastGroundHit;
    Vector3 SnapPosition => transform.position - Vector3.up * (LastGroundHit.distance - 0.05f);
    bool isOnGround => Physics.SphereCast(new Ray(transform.position + Vector3.down * 0.45f, Vector3.down), 0.5f, out LastGroundHit, 0.15f + (m_currentVelocity.y * SC_TimeManager.deltaTime), (1<<7));

    #region LaunchVisualizer
    GameObject m_launchVisualizer;
    GameObject LaunchVizualizer
    {
        get
        {
            if (!m_launchVisualizer && Camera.main)
                foreach (GameObject _obj in GameObject.FindGameObjectsWithTag("LaunchVisualizer"))
                    if(_obj.transform.parent.parent.gameObject == Camera.main.gameObject)
                    {
                        m_launchVisualizer = _obj;
                        break;
                    }

            return m_launchVisualizer;
        }
    }
    #endregion

    IEnumerator Start()
    {
        while (!Camera.main)
        {
            Debug.Log("is there a camera yet");
            yield return null;
        }

        LaunchVizualizer?.SetActive(false);
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 _lateralMomentum = new Vector3(m_momentumVelocity.x, 0, m_momentumVelocity.z);

        /*if (m_cameraHolder)
            m_cameraHolder.localPosition = new Vector3(0, -Mathf.Lerp(-1f, 0.5f, _lateralMomentum.magnitude / m_runSpeed), 0);*/

        switch (currentState)
        {
            case PlayerState.onGround:
                MoveGround();
                break;
            case PlayerState.falling:
                MoveAir();
                CheckForLaunch();
                if (currentState == PlayerState.falling)
                    CheckForGround();
                break;
            case PlayerState.jumping:
                MoveAir();
                CheckForFall();
                break;
            case PlayerState.launching:
                MoveAir();
                if (currentState == PlayerState.launching)
                   CheckForGround();
                break;
            case PlayerState.readyToLaunch:
                MoveAir();
                TryLaunch();
                if (currentState == PlayerState.readyToLaunch)
                    CheckForGround();
                break;
            case PlayerState.landing:
                
                break;

        }
    }
    void MoveGround()
    {
        //enables and disables the head bobbing
        headBob.amplitude = m_headBobStrength * (lateralVelocity.magnitude / m_runSpeed);

        float angleTowardsTarget = Vector3.Angle(m_currentVelocity, TargetVelocity - m_currentVelocity);

        if (angleTowardsTarget > 90)
        {
            m_currentVelocity = Vector3.Lerp(m_currentVelocity, TargetVelocity, m_slowFactor);
        }
        else
        {
            // Exponential method
            m_currentVelocity = Vector3.Lerp(m_currentVelocity, TargetVelocity, (m_currentVelocity.magnitude <= m_walkSpeed ? m_walkLerpFactor : m_runLerpFactor) * Time.deltaTime);
        }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            m_currentVelocity.y = jumpStrength;
        }

        m_momentumVelocity = Vector3.MoveTowards(m_momentumVelocity, Vector3.zero, m_momentumDecayFactor * SC_TimeManager.deltaTime);

        if (isOnGround)
        {
            m_currentVelocity.y = 0;
            transform.position = SnapPosition;

            if (Input.GetKeyDown(KeyCode.Space))
            {
                currentState = PlayerState.jumping;
                return;
            }
            else
            {
                Controller?.Move((m_currentVelocity + m_momentumVelocity) * SC_TimeManager.deltaTime);
            }
        }
        else
        {
            currentState = PlayerState.falling;
        }
    }

    void MoveAir ()
    {
        Debug.Log("is this moving?");
        m_momentumVelocity.y = Mathf.MoveTowards(m_momentumVelocity.y, terminalVelocity, gravityStrength * Time.deltaTime);
        m_momentumVelocity.x = Mathf.MoveTowards(m_momentumVelocity.x, 0, 2f * Time.deltaTime);
        m_momentumVelocity.z = Mathf.MoveTowards(m_momentumVelocity.z, 0, 2f * Time.deltaTime);

        if (m_momentumVelocity.y <=  0 && isOnGround)
        {
            currentState = PlayerState.onGround;
        }
        else
        {
            Debug.Log(m_momentumVelocity * Time.deltaTime);
            Controller?.Move(m_momentumVelocity * SC_TimeManager.deltaTime);
        }
    }

    void CheckForFall ()
    {
        if (m_momentumVelocity.y <= 0)
            currentState = PlayerState.falling;
    }

    void CheckForGround ()
    {
        if (isOnGround)
        {
            currentState = PlayerState.onGround;
        }
    }

    void CheckForLaunch ()
    {
        //launching player up after below 0 on the y
        if (transform.position.y < 0)
        {
            SC_TimeManager.DilateTime(0.5f);

            currentState = PlayerState.readyToLaunch;
        }
    }

    void TryLaunch  ()
    {
        if (Input.GetKey(KeyCode.Mouse0))
        {
            currentState = PlayerState.launching;
        }
    }

    void LaunchInCameraDirection()
    {
        m_momentumVelocity = Camera.main.transform.forward * m_launchForce;
        currentState = PlayerState.launching;
    }
}
Editor is loading...
Leave a Comment