Jump event not working properly

There seems to be a bug in my code somewhere, I’ve spent over a day trying all kinds of things, and nothing seems to work. So what is happening is that I get into the jumping state, and if the surface has a positive slope, the player basically glides over the landing area until it falls off the landing area, or runs into something, and then everything goes back to normal.

Here is a link to a video of what is happening

Here is the jumping state from the Complete 3rd Person Combat System for an RPG in Unity! course

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

public class PlayerJumpingState : PlayerBaseState
{
    private readonly int JumpHash = Animator.StringToHash("Jump");
    private const float CrossFadeDuration = 0.1f;
    private Vector3 momentum;

    public PlayerJumpingState(PlayerStateMachine stateMachine) : base(stateMachine) { }
    

    public override void Enter()
    {
        stateMachine.ForceReceiver.Jump(stateMachine.JumpForce);

        momentum = stateMachine.CharacterController.velocity;
        momentum.y = 0;

       stateMachine.Animator.CrossFadeInFixedTime(JumpHash, CrossFadeDuration);
    }

    public override void Tick(float deltaTime)
    {
        Move(momentum, deltaTime);
       // momentum.z -= deltaTime;
        
        if(stateMachine.CharacterController.velocity.y <= 0) 
        { 
            stateMachine.SwitchState(new PlayerFallingState(stateMachine));
            return;
        }
        FaceTarget();
    }

public override void Exit()
    {
        
    }

}

The jumping state (in the video, too) looks fine to me. I think the problem is in the falling state. Can you show that instead?

Hi, thank you for your answer and sure, here it is:

using System.Collections;
using System.Collections.Generic;
using UnityEditor.Rendering;
using UnityEngine;



public class PlayerFallingState : PlayerBaseState
{
    private readonly int FallHash = Animator.StringToHash("Fall");
    private const float CrossFadeDuration = 0.1f;
    private Vector3 momentum;


    public PlayerFallingState(PlayerStateMachine stateMachine) : base(stateMachine) { }


    public override void Enter()
    {
        momentum = stateMachine.CharacterController.velocity;
        momentum.y = 0;
        stateMachine.Animator.CrossFadeInFixedTime(FallHash, CrossFadeDuration);
    }

    public override void Tick(float deltaTime)
    {
        Move(momentum, deltaTime);

        if(stateMachine.CharacterController.isGrounded)
        {
            Debug.Log("PLAYER IS GROUNDED");
            ReturnToLocomotion();
        }

        FaceTarget();
    }

    public override void Exit()
    {

    }

}

That looks way cool! Changing the animation to a flying animation and you’ve got a super hero!
But that’s probably not the way we want jump to work…

The PlayerJumpingState looks fine.

I see two possibilities

  • The Force Receiver isn’t reducing y fast enough (should be Physics.Gravity.y)
  • The jumping state is getting called multiple times…

Paste in your Force Receiver and we’ll take a look.

That looks ok, too. Can you put Debug.Log on the jump state when it transitions to falling, and you already have one when it should return to locomotion. Then we can track at what point we are in which state. I have added a slope to my own project and this doesn’t happen for me.

Also what @Brian_Trotter said; ForceReceiver may help, too

Hello Brian and thank you for your answer, here is the code for the ForceReceiver:

using System.Collections;
using System.Collections.Generic;
//using System.Numerics;
using UnityEngine;
using UnityEngine.AI;

public class ForceReceiver : MonoBehaviour
{
    private float verticalVelocity;
    private Vector3 impact;
    private Vector3 dampingVelocity;
    public Vector3 Movement => impact + Vector3.up* verticalVelocity;

    [SerializeField] private CharacterController characterController;
    [SerializeField] private float drag = 0.3f;
    [SerializeField] private NavMeshAgent agent;
    private void Update()
    {
        if(verticalVelocity < 0 && characterController.isGrounded)
        {
            verticalVelocity= Physics.gravity.y * Time.deltaTime; ;
        }

        else
        {
            verticalVelocity += Physics.gravity.y * Time.deltaTime;
        }

        impact = Vector3.SmoothDamp(impact, Vector3.zero, ref dampingVelocity, drag );
       
        if(agent != null)
        {
           if (impact.sqrMagnitude < 0.2f * 0.2f)
           {
                impact = Vector3.zero;
                agent.enabled = true;
           }
        }
        

    }

    public void AddForce(Vector3 force)
    {
        impact+= force;

        if(agent!= null)
        {
            agent.enabled= false;
        }
    }

    public void Jump(float jumpforce)
    {
        verticalVelocity += jumpforce;
    }
}

So close with the formatting, the three apostrophes are the backwards ones next to the 1 and above the tab on your keyboard ```, not ‘’’

The ForceReceiver looks good too. This brings me back to the idea that the JumpingState may be happening multiple times. We can test this with a debug in PlayerJumpingState’s Enter method:

Debug.Log("Player Jumping State Entered at {Time.time}");

The Time.time will keep these Debugs on separate lines. My prediction is that you’ll get more and more of these debugs each time you jump, based on what I’m seeing in the video.

My apologies on the formatting, I am very new here :(, Im going to try that rn and I will let you know, I got a feeling you are correct

No worries, I edited the prior code posts for you. We all have to learn to format sometime. :slight_smile:

I just tried that and it only logs to the console one line per key press, so I dont think its being called multiple times in a row :frowning:

Had it been that, the solution would have been to make sure you unsubscribe from the Jump event in the exits of any states that call Jump, but that doesn’t appear to be the case.

I have to go to work, and it’ll be a long day for me, I may not get back to questions today. Zip up your project (remove the Library folder!) and upload it to https://gdev.tv/projectupload and I’ll take a look at it as soon as I can.

OK I understand and thank you both so much, I will surely upload it asap! I’m supposed to be in class rn but I’m obsessed with this bug hah, this is what Im going to school for I really want to do this for a living so things like this bother me a lot hehe

I think the character controller is not detecting the ground. The character is sliding up the hill, while falling… Do you have a collider on your character? There shouldn’t be one, but it’s worth checking

The funny thing is that I can walk up on the rock just fine, and when I jump from a standing position it works just fine, but when I have momentum it glides

Yeah, in my own project (after I added the slope) I can jump walking up the slope and standing still on the slope, but when I walk down the slope I can not. This is because the character moves forward and then does not touch the ground anymore. The ForceReceiver detects this and applies gravity to the character, pulling it down to the ground again. But my jump event fires in between walking and the ForceReceiver pulling me down, so I am never touching the ground when I try to jump walking down the slope. I’ll have to fix that.

Your character appears to slide along the ground because a collider is touching the ground and not allowing it to go further down, but the character controller is not close enough to the ground to detect that it is grounded so it stays in the falling state.

OK so I got this character from Mixamo, and in mixamorig:Hips there is a box collider and a rigidbody, the collideris not set to Trigger and the rigidbody has Use gravity checked

I don’t think it’s that one. Can you share a screenshot of your character in the hierarchy? Would also like to see what the Character Controller settings are

I also just noticed that the box collider gets disabled as soon as I run the game, and ok I will do that rn

image

I actually wanted to see the player with all its colliders and stuff. Just a note, the skin width should be around the same or more than 10% of the radius. So, in your case 0.025f. Not gonna fix your issue, though

I just reproduced this sliding behaviour, but I also had a slope of 44°. I kinda know why it’s happening, but I don’t know how to fix it without creating a custom ‘grounded’ check.

image

In the first image, the slope is ‘shallow’ enough that the ground detection (red arrow) can still hit it, but when the slope gets too steep it just can’t and we’re stuck in falling mode… And there’s no way of changing the range of the ground check.

Privacy & Terms