Wall Running

 avatar
unknown
csharp
22 days ago
3.0 kB
4
Indexable
using StarterAssets;
using UnityEngine;

public class WallRunning : MonoBehaviour
{
    [Header("Wall Running Settings")]
    public LayerMask wallLayer; // Layer for walls
    public float wallRunSpeed = 6f; // Speed while wall running
    public float wallRunGravity = -2f; // Gravity applied during wall run
    public float maxWallRunTime = 2f; // Maximum time to wall run
    public float jumpOffForce = 10f; // Force applied when jumping off the wall

    private CharacterController _controller;
    private ThirdPersonController _playerController;
    public bool isWallRunning = false;
    private float wallRunTimer;
    private Vector3 wallNormal;

    private void Start()
    {
        _controller = GetComponent<CharacterController>();
        _playerController = GetComponent<ThirdPersonController>();
    }

    private void Update()
    {
        if (isWallRunning)
        {
            HandleWallRun();
        }
        else
        {
            CheckForWallRun();
        }
    }

    private void CheckForWallRun()
    {
        if (!_playerController.Grounded && _playerController._input.move != Vector2.zero)
        {
            bool wallRight = Physics.Raycast(transform.position, transform.right, out RaycastHit rightHit, 1f, wallLayer);
            bool wallLeft = Physics.Raycast(transform.position, -transform.right, out RaycastHit leftHit, 1f, wallLayer);

            if (wallRight || wallLeft)
            {
                StartWallRun(wallRight ? rightHit.normal : leftHit.normal);
            }
        }
    }

    private void StartWallRun(Vector3 normal)
    {
        isWallRunning = true;
        wallNormal = normal;
        wallRunTimer = maxWallRunTime;
        _playerController._verticalVelocity = 0; // Reset vertical velocity
        _playerController._input.wallRun = true; // Set wall run input to true
    }

    public void HandleWallRun()
    {
        if (wallRunTimer <= 0 || _playerController.Grounded)
        {
            StopWallRun();
            return;
        }

        wallRunTimer -= Time.deltaTime;

        // Calculate the forward direction for wall running
        Vector3 wallForward = Vector3.Cross(wallNormal, Vector3.up).normalized;

        // Move the character along the wall
        _controller.Move(wallForward * wallRunSpeed * Time.deltaTime);

        // Apply reduced gravity
        _playerController._verticalVelocity += wallRunGravity * Time.deltaTime;

        // Check for jump input to jump off the wall
        if (_playerController._input.jump)
        {
            JumpOffWall();
        }
    }

    private void JumpOffWall()
    {
        StopWallRun();
        _playerController._verticalVelocity = jumpOffForce; // Apply jump force
    }

    private void StopWallRun()
    {
        isWallRunning = false;
        _playerController._input.wallRun = false; // Set wall run input to false
    }
}
Leave a Comment