Делаю бег по стене, персонаж не выходит из стейта "wallrunning"

Делаю по тутору систему бега по стене, персонаж заходит в стейт бега по стене, однако не выходит из него. Потратил немало времени но так и не смог решить этот момент. Подумал, что из-за того что у меня всего один стейт проблема, сделал стейт ходьбы но проблема была не в этом. Пробовал сделать включение гравитации после выхода из состояния волрана, тоже не сработало.

Вот демонстрация: https://youtu.be/y4POPMRsjg4?si=xVXUcZJNsDtSRDMm

PlayerMovement

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    [Header("Speed Display")]
    public float speed; //переменная для проверки скорости



    [Header("Movement")]
    public float moveSpeed;

    public float groundDrag;

    public float jumpForce;
    public float jumpCooldown;
    public float airMultiplayer;
    public float wallRunSpeed;
    bool readyToJump = false;

    [Header("Keybinds")]
    public KeyCode jumpKey = KeyCode.Space;

    [Header("Ground Check")]
    public float playerHeight;
    public LayerMask whatIsGround;
    bool grounded;

    [Header("References")]
    public Transform orientation;
    private Rigidbody rb;

    public MovementState state;
    public enum MovementState
    {
        
        wallrunning
        
    }

    public bool wallrunning;
    [Header("Input")]
    float horizontalInput;
    float verticalInput;

    Vector3 moveDirection;

    

    private void Start()
    {
        //gameObject.GetComponent<PlayerMovement>().enabled = false;
        StartCoroutine(CalcSpeed());
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true; //если не будет фриза, то игрок упадет (?)
        readyToJump = true;
    }


    private void Update()
    {
        //ground check
        grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
        MyInput();

        //hangle drag
        if (grounded)
            rb.drag = groundDrag;
        else
            rb.drag = 0;
    }


    private void FixedUpdate()
    {
        MovePlayer();
        SpeedControl();
    }
    private void MyInput()
    {
        if (Input.GetKey(jumpKey) && readyToJump && grounded)
        {
            readyToJump = false;

            Jump();

            Invoke(nameof(ResetJump), jumpCooldown);
        }
        horizontalInput = Input.GetAxisRaw("Horizontal");
        verticalInput = Input.GetAxisRaw("Vertical");
    }


    private void MovePlayer()
    {
        //calculate movement direction
        moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
        if (grounded)
            rb.AddForce(moveDirection * moveSpeed * 10f, ForceMode.Force);
        else if (!grounded)
            rb.AddForce(moveDirection * moveSpeed * 10f * airMultiplayer, ForceMode.Force);
    }


    private void SpeedControl() 
    {
        Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);

        if (flatVel.magnitude > moveSpeed)
        {
            Vector3 limitedVel = flatVel.normalized * moveSpeed;
            rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
        }
    }

    // дисплей скорости
    IEnumerator CalcSpeed()
    {
        bool isPlaying = true;

        while (isPlaying)
        {
            Vector3 prevPos = transform.position;
            yield return new WaitForFixedUpdate();
            speed = Mathf.RoundToInt(Vector3.Distance(transform.position, prevPos) / Time.fixedDeltaTime);
        }
        
    } 


    private void Jump()
    {
        rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);

        rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);

    }
    private void ResetJump()
    {
        readyToJump = true;
    }


    private void StateHandler()
    {
        //Mode - wallrunning
        if (wallrunning)
        {
            state = MovementState.wallrunning;
            moveSpeed = wallRunSpeed;
        }
    }
}

Wallrun

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WallRun : MonoBehaviour
{
    [Header("Wallrun")]
    public LayerMask whatIsWall;
    public LayerMask whatIsGround;
    public float wallRunForce;
    public float maxWallRunTime;
    private float wallRunTimer;

    [Header("Detection")]
    public float wallCheckDistance;
    public float minJumpHeight;
    private RaycastHit leftWallHit;
    private RaycastHit rightWallHit;
    private bool wallLeft;
    private bool wallRight;

    [Header("Input")]
    float horizontalInput;
    float verticalInput;

    [Header("References")]
    public Transform orientation;
    private Rigidbody rb;
    private PlayerMovement pm;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        pm = GetComponent<PlayerMovement>();
    }


    void Update()
    {
        CheckForWall();
        StateMachine();
    }


    private void FixedUpdate()
    {
        if (pm.wallrunning)
            WallRunningMovement();
        
    }
    private void CheckForWall()
    {
        wallRight = Physics.Raycast(transform.position, /*Vector3.left*/orientation.right, out rightWallHit, wallCheckDistance, whatIsWall);
        wallLeft = Physics.Raycast(transform.position, /*Vector3.left*/-orientation.right, out leftWallHit, wallCheckDistance, whatIsWall);

    }


    private bool AboveGround()
    {
        return !Physics.Raycast(transform.position, Vector3.down, minJumpHeight, whatIsGround);
    }


    private void StateMachine()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
        verticalInput = Input.GetAxisRaw("Vertical");

        if((wallLeft || wallRight) && verticalInput > 0 && AboveGround())
        {
            if (!pm.wallrunning)
            {
                StartWallRun();
            }
            else 
            {
                if(pm.wallrunning)
                    StopWallRun();
            }
        }
    }


    private void StartWallRun()
    {
        pm.wallrunning = true;
    }


    private void WallRunningMovement()
    {
        rb.useGravity = false;
        rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);

        Vector3 wallNormal = wallRight ? rightWallHit.normal : leftWallHit.normal;

        Vector3 wallForward = Vector3.Cross(wallNormal, transform.up);

        rb.AddForce(wallForward * wallRunForce, ForceMode.Force);
    }


    private void StopWallRun()
    {
        pm.wallrunning = false;
    }
}

Ответы (0 шт):