[Released] Kinematic Character Controller

Is there no built in way to enable air control on the character when in the air, like during a jump, the character goes perfectly straight and doesnt allow input to steer it in midair?
Its not very realistic but absolutely a must for jumping puzzles D;

Has anyone figured out how to cleanly achieve mid air control?

Thanks.

There actually is, I donā€™t remeber what the variable was called though, but maybe it was something like air velocity control

1 Like

yeah it works by adjusting air acceleration, but doesnt let you increase it more than a little unless you want to go supersonic speed while in the air, which is not wantedā€¦ so you only have a little air controlā€¦

I think there is a setting to limit air speed, maybe limit it to the same value as movement speed

Itā€™s really up to how you configure the character controller. The general way I do it involves checking to see if youā€™re on stable ground, and if so, allow movement. But if I donā€™t do that check, and just always allow the player to control their velocity, then that allows them to control the character in air.

Make sure you go through the included tutorials so you understand how all the functions work. This isnā€™t really a character controller to be used just out-of-box, youā€™re expected to have some experience coding to create a character controller to your liking. The system handles a lot under the hood, but velocity is not controlled for you, you move the character however you want in the controller through the character motor, and it handles the rest for you

Iā€™m posting this in case anyone else runs into this issue. In my game I found that a bug was introduced after updating to the latest version of KinematicCharacterController. I stop my moving platforms by setting enabled to false on the PhysicsMover component (is that the wrong way to do it?). This unregisters the physics mover and stops the platformā€™s position from being updated. What I found with the latest version is that my character will drift if it stands on the platform after it has been stopped. I resolved this by setting Velocity and AngularVelocity to zero in PhysicsMover.OnDisable().

private void OnDisable()
{
   // begin bug fix
   Velocity = Vector3.zero;
   AngularVelocity = Vector3.zero;
   // end bug fix

   KinematicCharacterSystem.UnregisterPhysicsMover(this);
}
2 Likes

One thing I have noticed after the update to the latest version, is that when I go up a small incline my character launches like a vehicle driving off of a ramp. My game is a first person shooter so this is not appropriate. Has anyone else noticed this?

Update: I fixed it by increasing ā€œMax Stable Slope Angleā€

this controller is very, very good but can anyone tell me a good way to remove all of the interpolation/smoothing from camera and player rotation for the sake of a first person shooter, i feel like i have bypassed 10 slerp functions related to it but there is allways some left

Hello. I know youā€™ve been asking this question for a long time. Did you manage to find a solution to make the capsule or other collider horizontal?

Very simple question, how to prevent the KCC from pushing any Rigidbody ? Setting RigidbodyInteractionType to None doesnā€™t change anything.

I also removed this line :
bodyHit.Rigidbody.AddForceAtPosition(velocityChangeOnBody, bodyHit.HitPoint, ForceMode.VelocityChange);
but it doesnā€™t have any effect. Rigidbodies are still getting pushed.

If an object has a collider at all, youā€™ll push rigidbodies, thatā€™s just how the physics engine works. You can set up the collision layers to prevent certain objects from being touched by your player, but your player in turn wonā€™t be able to bump against them.

If you donā€™t want a certain object to be pushed at all, either remove the rigidbody or mark the rigidbody as kinematic. Kinematic just basically equates to ā€œthis thing wonā€™t be effected by other forces in the physics engineā€

Or modify KCC Motor to treat that non-kinematic rigidbody as kinematic.

Hey, Iā€™m trying to create a lock on movement around target (character should always rotate around target, including when in air/jumping). something similar to Darksiderā€™s 2 lock on movement.
does anyone have any idea how to achieve it with KCC?

Iā€™ve managed to get it working for ground movement, however Iā€™m having trouble maintaining orbit speed when player is jumping and adding the ground smoothing factor for movement.
hereā€™s what I have so far (code is mostly based on tutorial scripts in package):

// called in UpdateVelocity when motor.GroundingStatus.IsStableOnGround = true
  private void UpdateGroundVelocity(ref Vector3 currentVelocity, float deltaTime)
    {
        // Reorient source velocity on current ground slope (this is because we don't want our smoothing to cause any velocity losses in slope changes)
        currentVelocity = motor.GetDirectionTangentToSurface(currentVelocity, motor.GroundingStatus.GroundNormal) *
                          currentVelocity.magnitude;

        // Calculate target velocity
        var targetMovementVelocity = GetGroundOrbitVelocity(deltaTime);

        // Smooth movement Velocity
        // TODO: fix velocity smoothing
        currentVelocity = targetMovementVelocity;
        // currentVelocity = Vector3.Lerp(currentVelocity, targetMovementVelocity,
        //     1 - Mathf.Exp(-groundMovementSharpness * deltaTime));
    }

private Vector3 GetGroundOrbitVelocity(float deltaTime)
    {
        // if no left/right input or if there's forward/backward input
        // then "break" orbit movement and use standard orientation movement
        if (Mathf.Abs(_initialInputVector.y) > 0 || _initialInputVector.x == 0)
        {
            var inputRight = Vector3.Cross(_moveInputVector, motor.CharacterUp);
            var reorientedInput = Vector3.Cross(motor.GroundingStatus.GroundNormal, inputRight).normalized *
                                  _moveInputVector.magnitude;
            var targetMovementVelocity = reorientedInput * groundMoveSpeed;
            return targetMovementVelocity;
        }
       
        UpdateOrbitHelperPosition(deltaTime, groundMoveSpeed);

        var velocityForMovePosition =
            motor.GetVelocityForMovePosition(motor.TransientPosition, orbitHelper.position, deltaTime);
        return velocityForMovePosition;
    }

// using a transform helper to calculate RotateAround correctly
private void UpdateOrbitHelperPosition(float deltaTime, float moveSpeed)
    {
        orbitHelper.position = motor.TransientPosition;
        var lockOnPosition = lockOnTransform.position;
        var distanceToOrbit = Vector3.Distance(motor.TransientPosition, lockOnPosition);
        var angle = 2 * Mathf.Asin(0.5f * moveSpeed * _initialInputVector.x * deltaTime / distanceToOrbit) *
                    Mathf.Rad2Deg;
       
        // character up need to change if planet gravity is not straight up
        orbitHelper.RotateAround(lockOnPosition, motor.CharacterUp, -angle);
    }

if anyone knows how i can get it working in air and add smoothing to movement

Hi everybody. Iā€™m currently working on creating a FPS character movement with this KCC and having a hard time implementing the separate speeds for walking forward and walking strafe based on the ExampleCharacterController. Here are the SetInputs function which takes in the userā€™s wasd input and the UpdateVelocity function at the moment.
It would mean a lot to me if anyone could help me figure this out!
Thank you in advance!


I want to make it look kinda like the following code which I implemented as the first iteration of the character controller.

private void CalculateMovement()
{
    if(input_Movement.y <= 0.2f)
    {
        isSprinting = false;
    }

    var verticalSpeed = playerSettings.WalkingForwardSpeed;
    var horizontalSpeed = playerSettings.WalkingStrafeSpeed;

    // Multiplying player movement speed by sprinting speed when sprinting
    if(isSprinting)
    {
        verticalSpeed = playerSettings.RunningForwardSpeed;
        horizontalSpeed = playerSettings.RunningStrafeSpeed;
    }

    // Speed effectors for when the player is in a different motion
    if(!characterController.isGrounded)
    {
        // Remove comment out to slow down the player when jumping
        // playerSettings.SpeedEffector = playerSettings.FallingSpeedEffector;
    }
    else if (playerStance == PlayerStance.Crouch)
    {
        playerSettings.SpeedEffector = playerSettings.CrouchSpeedEffector;
    }
    else if (playerStance == PlayerStance.Prone)
    {
        playerSettings.SpeedEffector = playerSettings.ProneSpeedEffector;
    }
    else
    {
        playerSettings.SpeedEffector = 1;
    }

    // Slowing down player's movement speed when ADS by some percent
    if(weaponController.fireable != null)
    {
        playerSettings.SpeedEffector = playerSettings.SpeedEffector * weaponController.fireable.CalculateADSMovementSlownessSpeedEffector();
    }

    verticalSpeed *= playerSettings.SpeedEffector;
    horizontalSpeed *= playerSettings.SpeedEffector;

    newMovementSpeed = Vector3.SmoothDamp(newMovementSpeed, new Vector3(horizontalSpeed * input_Movement.x * Time.deltaTime, 0, verticalSpeed * input_Movement.y * Time.deltaTime), ref newMovementSpeedVelocity, characterController.isGrounded ? playerSettings.MovementSmoothing : playerSettings.FallingSmoothing);

    var movementSpeed = transform.TransformDirection(newMovementSpeed);
}

I did it! I have successfully implemented the feature above so hereā€™s how to do it, in case you need to know!
I changed the lines that are highlighted with selection for SetInputs and UpdateVelocity functions.
9932826--1437588--upload_2024-7-10_19-57-43.png
9932826--1437591--upload_2024-7-10_19-57-53.png
9932826--1437597--upload_2024-7-10_19-58-41.png
What I did was multiply strafe and forward speed to the input rather than to reorientedInput. And because the _moveInputVector is no longer a normalized Vector3, in order for the air movement to stay consistent across the original code and the new code, I normalized the _moveInputVector which is multiplied by AirAccelerationSpeed * deltaTime in the else that handles the air movement.

9932826--1437594--upload_2024-7-10_19-57-59.png

Does any1 had problem with KCC with rootmotion and cinemachine freelook? For me itā€™s jitter a lot doesnt matter if i set interpolation, different update types etc.
Even on rootmotion example (Minimum replication project), if i add cinemachine brain + cinemachine freelook camera, the example jitters a lot.

Hi, Iā€™m using this character controller and I really love it so far but Iā€™m confused on how to make a mancannon to throw my character. Rigidbody.addforce doesnā€™t seem to do anything, neither does setting rigidbody velocity. I assume thatā€™s because the KCC is dictating all this kind of stuff?

Iā€™d like to throw my character across the map when he steps on a trigger, how do I do that with your controller?

Great package! Iā€™m currently using it in my project, and itā€™s working really well overall. However, Iā€™m encountering an issue when implementing multiplayer. While the first player can push rigidbodies as expected, the second player seems unable to interact with or push them.

Has anyone else encountered this problem in a multiplayer setup? Any ideas on what might be causing this, or suggestions for how to resolve it?

Iā€™m using NFGO.

Thanks in advance for any help!