Wall Running
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