Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug The character sticks to the wall when jumping, and I can move along it in the air.

Discussion in 'Scripting' started by Seeanax, Oct 5, 2023.

  1. Seeanax

    Seeanax

    Joined:
    Nov 6, 2022
    Posts:
    4
    I have a character from the asset store, and when I jump and look slightly towards the wall with the camera and press the W key or any other key for movement, there is a bug condition where the camera is facing the wall. Then, after jumping in the air, I can hang on the wall without touching the ground, walk on the wall, and I don't even fall, even though I thought it should be like in real life. I mean, if you jump into a wall, you shouldn't just stick to it and start floating in the air, right? I couldn't come up with a solution for this. I wanted to make it so that when the player jumps or simply gets close to the wall, it doesn't stick to the wall, even if they are looking at it with the camera and pressing keys like forward or backward, etc. The same applies to jumping. If the player jumps, they should just collide with the wall, stop, and fall down. If they hit the wall at an angle, their speed should decrease, and they should also fall down. How can this be fixed? I can provide the code for character movement and the code for jumping (the jump code is separate). Here are some screenshots where I'm stuck in the air, and at that moment, I'm holding down the W key to do this. I don't want it to be like this; please help me fix it!

    Video
    |
    |
    \/

    video at the very bottom (accessible via the link).




    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class FirstPersonMovement : MonoBehaviour
    5. {
    6.     public enum CharacterState
    7.     {
    8.         Grounded, // Находится на земле.
    9.         Jumping,  // В процессе прыжка.
    10.         WallSlide // Столкнулся со стеной.
    11.     }
    12.  
    13.     Jump jumpComponent;
    14.  
    15.     public float speed = 5;
    16.  
    17.     [Header("Running")]
    18.     public bool canRun = true;
    19.     public bool IsRunning { get; private set; }
    20.     public float runSpeed = 9;
    21.     public KeyCode runningKey = KeyCode.LeftShift;
    22.  
    23.     Rigidbody rigidbody;
    24.     public List<System.Func<float>> speedOverrides = new List<System.Func<float>>();
    25.  
    26.     void Awake()
    27.     {
    28.         rigidbody = GetComponent<Rigidbody>();
    29.     }
    30.  
    31.     void FixedUpdate()
    32.     {
    33.         IsRunning = canRun && Input.GetKey(runningKey);
    34.  
    35.         float targetMovingSpeed = IsRunning ? runSpeed : speed;
    36.         if (speedOverrides.Count > 0)
    37.         {
    38.             targetMovingSpeed = speedOverrides[speedOverrides.Count - 1]();
    39.         }
    40.  
    41.         Vector2 targetVelocity = new Vector2(Input.GetAxis("Horizontal") * targetMovingSpeed, Input.GetAxis("Vertical") * targetMovingSpeed);
    42.  
    43.         rigidbody.velocity = transform.rotation * new Vector3(targetVelocity.x, rigidbody.velocity.y, targetVelocity.y);
    44.     }
    45. }
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Crouch : MonoBehaviour
    4. {
    5.     public KeyCode key = KeyCode.LeftControl;
    6.  
    7.     [Header("Slow Movement")]
    8.     [Tooltip("Movement to slow down when crouched.")]
    9.     public FirstPersonMovement movement;
    10.     [Tooltip("Movement speed when crouched.")]
    11.     public float movementSpeed = 2;
    12.  
    13.     [Header("Low Head")]
    14.     [Tooltip("Head to lower when crouched.")]
    15.     public Transform headToLower;
    16.     [HideInInspector]
    17.     public float? defaultHeadYLocalPosition;
    18.     public float crouchYHeadPosition = 1;
    19.  
    20.     [Tooltip("Collider to lower when crouched.")]
    21.     public CapsuleCollider colliderToLower;
    22.     [HideInInspector]
    23.     public float? defaultColliderHeight;
    24.  
    25.     public bool IsCrouched { get; private set; }
    26.     public event System.Action CrouchStart, CrouchEnd;
    27.  
    28.  
    29.     void Reset()
    30.     {
    31.         // Try to get components.
    32.         movement = GetComponentInParent<FirstPersonMovement>();
    33.         headToLower = movement.GetComponentInChildren<Camera>().transform;
    34.         colliderToLower = movement.GetComponentInChildren<CapsuleCollider>();
    35.     }
    36.  
    37.     void LateUpdate()
    38.     {
    39.         if (Input.GetKey(key))
    40.         {
    41.             // Enforce a low head.
    42.             if (headToLower)
    43.             {
    44.                 // If we don't have the defaultHeadYLocalPosition, get it now.
    45.                 if (!defaultHeadYLocalPosition.HasValue)
    46.                 {
    47.                     defaultHeadYLocalPosition = headToLower.localPosition.y;
    48.                 }
    49.  
    50.                 // Lower the head.
    51.                 headToLower.localPosition = new Vector3(headToLower.localPosition.x, crouchYHeadPosition, headToLower.localPosition.z);
    52.             }
    53.  
    54.             // Enforce a low colliderToLower.
    55.             if (colliderToLower)
    56.             {
    57.                 // If we don't have the defaultColliderHeight, get it now.
    58.                 if (!defaultColliderHeight.HasValue)
    59.                 {
    60.                     defaultColliderHeight = colliderToLower.height;
    61.                 }
    62.  
    63.                 // Get lowering amount.
    64.                 float loweringAmount;
    65.                 if (defaultHeadYLocalPosition.HasValue)
    66.                 {
    67.                     loweringAmount = defaultHeadYLocalPosition.Value - crouchYHeadPosition;
    68.                 }
    69.                 else
    70.                 {
    71.                     loweringAmount = defaultColliderHeight.Value * .5f;
    72.                 }
    73.  
    74.                 // Lower the colliderToLower.
    75.                 colliderToLower.height = Mathf.Max(defaultColliderHeight.Value - loweringAmount, 0);
    76.                 colliderToLower.center = Vector3.up * colliderToLower.height * .5f;
    77.             }
    78.  
    79.             // Set IsCrouched state.
    80.             if (!IsCrouched)
    81.             {
    82.                 IsCrouched = true;
    83.                 SetSpeedOverrideActive(true);
    84.                 CrouchStart?.Invoke();
    85.             }
    86.         }
    87.         else
    88.         {
    89.             if (IsCrouched)
    90.             {
    91.                 // Rise the head back up.
    92.                 if (headToLower)
    93.                 {
    94.                     headToLower.localPosition = new Vector3(headToLower.localPosition.x, defaultHeadYLocalPosition.Value, headToLower.localPosition.z);
    95.                 }
    96.  
    97.                 // Reset the colliderToLower's height.
    98.                 if (colliderToLower)
    99.                 {
    100.                     colliderToLower.height = defaultColliderHeight.Value;
    101.                     colliderToLower.center = Vector3.up * colliderToLower.height * .5f;
    102.                 }
    103.  
    104.                 // Reset IsCrouched.
    105.                 IsCrouched = false;
    106.                 SetSpeedOverrideActive(false);
    107.                 CrouchEnd?.Invoke();
    108.             }
    109.         }
    110.     }
    111.  
    112.  
    113.     #region Speed override.
    114.     void SetSpeedOverrideActive(bool state)
    115.     {
    116.         // Stop if there is no movement component.
    117.         if (!movement)
    118.         {
    119.             return;
    120.         }
    121.  
    122.         // Update SpeedOverride.
    123.         if (state)
    124.         {
    125.             // Try to add the SpeedOverride to the movement component.
    126.             if (!movement.speedOverrides.Contains(SpeedOverride))
    127.             {
    128.                 movement.speedOverrides.Add(SpeedOverride);
    129.             }
    130.         }
    131.         else
    132.         {
    133.             // Try to remove the SpeedOverride from the movement component.
    134.             if (movement.speedOverrides.Contains(SpeedOverride))
    135.             {
    136.                 movement.speedOverrides.Remove(SpeedOverride);
    137.             }
    138.         }
    139.     }
    140.  
    141.     float SpeedOverride() => movementSpeed;
    142.     #endregion
    143. }
    Code (CSharp):
    1. using System.Linq;
    2. using UnityEngine;
    3.  
    4. public class FirstPersonAudio : MonoBehaviour
    5. {
    6.     public FirstPersonMovement character;
    7.     public GroundCheck groundCheck;
    8.  
    9.     [Header("Step")]
    10.     public AudioSource stepAudio;
    11.     public AudioSource runningAudio;
    12.     [Tooltip("Minimum velocity for moving audio to play")]
    13.     public float velocityThreshold = .01f;
    14.     Vector2 lastCharacterPosition;
    15.     Vector2 CurrentCharacterPosition => new Vector2(character.transform.position.x, character.transform.position.z);
    16.  
    17.     [Header("Landing")]
    18.     public AudioSource landingAudio;
    19.     public AudioClip[] landingSFX;
    20.  
    21.     [Header("Jump")]
    22.     public Jump jump;
    23.     public AudioSource jumpAudio;
    24.     public AudioClip[] jumpSFX;
    25.  
    26.     [Header("Crouch")]
    27.     public Crouch crouch;
    28.     public AudioSource crouchStartAudio, crouchedAudio, crouchEndAudio;
    29.     public AudioClip[] crouchStartSFX, crouchEndSFX;
    30.  
    31.     AudioSource[] MovingAudios => new AudioSource[] { stepAudio, runningAudio, crouchedAudio };
    32.  
    33.  
    34.     void Reset()
    35.     {
    36.         // Setup stuff.
    37.         character = GetComponentInParent<FirstPersonMovement>();
    38.         groundCheck = (transform.parent ?? transform).GetComponentInChildren<GroundCheck>();
    39.         stepAudio = GetOrCreateAudioSource("Step Audio");
    40.         runningAudio = GetOrCreateAudioSource("Running Audio");
    41.         landingAudio = GetOrCreateAudioSource("Landing Audio");
    42.  
    43.         // Setup jump audio.
    44.         jump = GetComponentInParent<Jump>();
    45.         if (jump)
    46.         {
    47.             jumpAudio = GetOrCreateAudioSource("Jump audio");
    48.         }
    49.  
    50.         // Setup crouch audio.
    51.         crouch = GetComponentInParent<Crouch>();
    52.         if (crouch)
    53.         {
    54.             crouchStartAudio = GetOrCreateAudioSource("Crouch Start Audio");
    55.             crouchedAudio = GetOrCreateAudioSource("Crouched Audio");
    56.             crouchEndAudio = GetOrCreateAudioSource("Crouch End Audio");
    57.         }
    58.     }
    59.  
    60.     void OnEnable() => SubscribeToEvents();
    61.  
    62.     void OnDisable() => UnsubscribeToEvents();
    63.  
    64.     void FixedUpdate()
    65.     {
    66.         // Play moving audio if the character is moving and on the ground.
    67.         float velocity = Vector3.Distance(CurrentCharacterPosition, lastCharacterPosition);
    68.         if (velocity >= velocityThreshold && groundCheck && groundCheck.isGrounded)
    69.         {
    70.             if (crouch && crouch.IsCrouched)
    71.             {
    72.                 SetPlayingMovingAudio(crouchedAudio);
    73.             }
    74.             else if (character.IsRunning)
    75.             {
    76.                 SetPlayingMovingAudio(runningAudio);
    77.             }
    78.             else
    79.             {
    80.                 SetPlayingMovingAudio(stepAudio);
    81.             }
    82.         }
    83.         else
    84.         {
    85.             SetPlayingMovingAudio(null);
    86.         }
    87.  
    88.         // Remember lastCharacterPosition.
    89.         lastCharacterPosition = CurrentCharacterPosition;
    90.     }
    91.  
    92.     void SetPlayingMovingAudio(AudioSource audioToPlay)
    93.     {
    94.         // Pause all MovingAudios.
    95.         foreach (var audio in MovingAudios.Where(audio => audio != audioToPlay && audio != null))
    96.         {
    97.             audio.Pause();
    98.         }
    99.  
    100.         // Play audioToPlay if it was not playing.
    101.         if (audioToPlay && !audioToPlay.isPlaying)
    102.         {
    103.             audioToPlay.Play();
    104.         }
    105.     }
    106.  
    107.     #region Play instant-related audios.
    108.     void PlayLandingAudio() => PlayRandomClip(landingAudio, landingSFX);
    109.     void PlayJumpAudio() => PlayRandomClip(jumpAudio, jumpSFX);
    110.     void PlayCrouchStartAudio() => PlayRandomClip(crouchStartAudio, crouchStartSFX);
    111.     void PlayCrouchEndAudio() => PlayRandomClip(crouchEndAudio, crouchEndSFX);
    112.     #endregion
    113.  
    114.     #region Subscribe/unsubscribe to events.
    115.     void SubscribeToEvents()
    116.     {
    117.         // PlayLandingAudio when Grounded.
    118.         groundCheck.Grounded += PlayLandingAudio;
    119.  
    120.         // PlayJumpAudio when Jumped.
    121.         if (jump)
    122.         {
    123.             jump.Jumped += PlayJumpAudio;
    124.         }
    125.  
    126.         // Play crouch audio on crouch start/end.
    127.         if (crouch)
    128.         {
    129.             crouch.CrouchStart += PlayCrouchStartAudio;
    130.             crouch.CrouchEnd += PlayCrouchEndAudio;
    131.         }
    132.     }
    133.  
    134.     void UnsubscribeToEvents()
    135.     {
    136.         // Undo PlayLandingAudio when Grounded.
    137.         groundCheck.Grounded -= PlayLandingAudio;
    138.  
    139.         // Undo PlayJumpAudio when Jumped.
    140.         if (jump)
    141.         {
    142.             jump.Jumped -= PlayJumpAudio;
    143.         }
    144.  
    145.         // Undo play crouch audio on crouch start/end.
    146.         if (crouch)
    147.         {
    148.             crouch.CrouchStart -= PlayCrouchStartAudio;
    149.             crouch.CrouchEnd -= PlayCrouchEndAudio;
    150.         }
    151.     }
    152.     #endregion
    153.  
    154.     #region Utility.
    155.     /// <summary>
    156.     /// Get an existing AudioSource from a name or create one if it was not found.
    157.     /// </summary>
    158.     /// <param name="name">Name of the AudioSource to search for.</param>
    159.     /// <returns>The created AudioSource.</returns>
    160.     AudioSource GetOrCreateAudioSource(string name)
    161.     {
    162.         // Try to get the audiosource.
    163.         AudioSource result = System.Array.Find(GetComponentsInChildren<AudioSource>(), a => a.name == name);
    164.         if (result)
    165.             return result;
    166.  
    167.         // Audiosource does not exist, create it.
    168.         result = new GameObject(name).AddComponent<AudioSource>();
    169.         result.spatialBlend = 1;
    170.         result.playOnAwake = false;
    171.         result.transform.SetParent(transform, false);
    172.         return result;
    173.     }
    174.  
    175.     static void PlayRandomClip(AudioSource audio, AudioClip[] clips)
    176.     {
    177.         if (!audio || clips.Length <= 0)
    178.             return;
    179.  
    180.         // Get a random clip. If possible, make sure that it's not the same as the clip that is already on the audiosource.
    181.         AudioClip clip = clips[Random.Range(0, clips.Length)];
    182.         if (clips.Length > 1)
    183.             while (clip == audio.clip)
    184.                 clip = clips[Random.Range(0, clips.Length)];
    185.  
    186.         // Play the clip.
    187.         audio.clip = clip;
    188.         audio.Play();
    189.     }
    190.     #endregion
    191. }
    192.  
    Code (CSharp):
    1. using Unity.VisualScripting;
    2. using UnityEngine;
    3.  
    4. public class Jump : MonoBehaviour
    5. {
    6.     Rigidbody rigidbody;
    7.     public float jumpStrength = 2;
    8.     public event System.Action Jumped;
    9.  
    10.  
    11.     [SerializeField, Tooltip("Prevents jumping when the transform is in mid-air.")]
    12.     GroundCheck groundCheck;
    13.  
    14.     void Reset()
    15.     {
    16.         // Try to get groundCheck.
    17.         groundCheck = GetComponentInChildren<GroundCheck>();
    18.     }
    19.  
    20.     void Awake()
    21.     {
    22.         // Get rigidbody.
    23.         rigidbody = GetComponent<Rigidbody>();
    24.     }
    25.  
    26.     void LateUpdate()
    27.     {
    28.         // Jump when the Jump button is pressed and we are on the ground or touching a wall.
    29.         if (Input.GetButtonDown("Jump") && (IsGrounded()))
    30.         {
    31.                 // В противном случае выполните обычный прыжок.
    32.                 rigidbody.AddForce(Vector3.up * 100 * jumpStrength);
    33.  
    34.             Jumped?.Invoke();
    35.         }
    36.     }
    37.  
    38.     bool IsGrounded()
    39.     {
    40.         return !groundCheck || groundCheck.isGrounded;
    41.     }
    42. }
    43.  


    Video:

     
  2. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    541
    Try adding a physics material with hardly any friction to your character.
     
    Seeanax likes this.
  3. Seeanax

    Seeanax

    Joined:
    Nov 6, 2022
    Posts:
    4
    Thank you so much!!!!!! You are the best person in the world!!! I've been struggling with this for a couple of days and couldn't figure out how to solve it, and I even asked neural networks, but it didn't help. This was my last option, asking on the forum, and if it hadn't worked, I don't know what I would have done. Thank you again, I am very grateful to you!!!
     
    zulo3d likes this.