Search Unity

[Released] Kinematic Character Controller

Discussion in 'Assets and Asset Store' started by PhilSA, Sep 29, 2017.

  1. Mirath

    Mirath

    Joined:
    Aug 5, 2012
    Posts:
    14
    And an example of the collider drift when pausing the simulation:
     

    Attached Files:

  2. heartshapedbox

    heartshapedbox

    Joined:
    May 27, 2018
    Posts:
    31
    Is there a way to get simulated position?
    I mean, i want to get a next calculated position not my character actually move.
    I'll cast a ray at that position and decide my character move or not.
    how can i get next calculated position?
     
  3. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    You can check overlaps with motor.CharacterCollisionsOverlap at that position, it wont actually simulate you moving there from your current one but if youre just teleporting this works well.

    Also since the character is a capsule I recommend to do a spherecast with the players radius downwards from the raycasts hit point + up vector to get a working position

    If youre not teleporting and I misunderstood you, you can use Motor.TransientPosition during the UpdateVelocity() phase to get the next position. Read the UpdateVelocity() part of the water swimming example movement script, this should be what you want. The part where it does this:
    Code (CSharp):
    1. Vector3 waterSurfaceNormal = (resultingSwimmingReferancePosition - closestPointWaterSurface).normalized;
    2. smoothedVelocity = Vector3.ProjectOnPlane(smoothedVelocity, waterSurfaceNormal);
    You just use your raycast hit normal or something as the surfaceNormal, that should work
     
  4. heartshapedbox

    heartshapedbox

    Joined:
    May 27, 2018
    Posts:
    31
    Thanks for the reply!

    I don't teleport. i want my character move along the wall (hanging the ledge and move side to side).
    and at first, i tried to use TransientPosition in UpdateVelocity() as you suggested,
    but it does not help because it was not different from transform.position.
    I want to cast the ray from next position, but it does not calculated yet.. right?

    TransientPosition value changes after the UpdateVelocity called.
    so i use TransientPosition in AfterCharacterUpdate().
    In AfterCharacterUpdate(), i cast a ray from TransientPosition and get a hitpoint,
    use Motor.SetPosition() to that hitpoin.
    but i'm not sure this is the correct way...
     
    Last edited: Nov 5, 2022
  5. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    The swimming example should do what you want though as it modifies the characters velocity so it never goes beyond the hit point/normal. Also transientPosition is likely very similar to your current one, since frames (and therefore positions) are very close together if you have lots of them xD
     
  6. heartshapedbox

    heartshapedbox

    Joined:
    May 27, 2018
    Posts:
    31
    ah, okay. i'll check swimming example again.thank you!!
     
  7. heartshapedbox

    heartshapedbox

    Joined:
    May 27, 2018
    Posts:
    31
    I solved my problem with your suggestion!
    Those who want to check simulated position in UpdateVelocity, "resultingSwimmingReferancePosition" is what you want.

    and i have another question,,
    in your project, does the character interact with object (pull or push or throw..) by KCC?
    or use different logic?

    Thank you again!!
     
    Vincent454 likes this.
  8. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    Awesome! I think if it collides with any physics objects it should push them away, with the rigidbody interaction settings in the kcc motor set to simulated dynamic
     
  9. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    How can i ensure that when i place a Kinematic Character Controller on a certain position, using motor.SetPosition, they wont fall through the ground colliders?

    At the moment i place them on our generated navmesh, and that sometimes causes our characters to fall through. What settings would affect this?
     
  10. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    I am spawning the player on the navmesh too, but never had that problem so far. The navmesh is only an approximation of the environment, so maybe its related to how detailed your generated navmesh is or if youre using colliders instead of meshes to generate it.

    Either way, maybe you can do a raycast downwards from the spawn position on the navmesh + 1 on the y axis or something and if it hits something, use that as the spawn position. You could also generate a height mesh instead of a navmesh which will be more accurate to the mesh/collider
     
  11. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Thanks! Using the heightmap is a great suggestion.
     
    Vincent454 likes this.
  12. socialtrens

    socialtrens

    Joined:
    Oct 23, 2017
    Posts:
    65
    Has someone tried putting Unity Ragdoll on top of PhysicMover? I did and it crashes Unity Editor. I need to restart afterwards and try again and it crashes again. Is PhysicMover incompatible with Unity Ragdoll? How to make it work?
     
  13. TAPE_EATER

    TAPE_EATER

    Joined:
    Nov 2, 2019
    Posts:
    15

    I'm trying to implement a ledge grab as well, I have two raycasts (forward, down) and two capsulecasts (up, forward) to detect when and where to hang (the hang position is the forward raycast.x and down.y).

    But when I set the position with "Motor.SetPosition", the character glitches for a frame and sometimes gets put at half the height of the object to hang on to. I'm guessing this is because it overlaps and I tried to work with the suggested motor.CharacterCollisionsOverlap but I'm not sure how to actually use it to set the character position.
    Would you mind elaborating?
     
  14. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    motor.CharacterCollisionsOverlap checks if a position can be safely occupied by the character, so only if it returns 0 (no overlaps found) you can move the character to the position you checked. So what you have to do ideally is have the position you check be where you will move the character and only check it to make sure it can go there and prevent the character from climbing if it cant.

    Though finding the ideal position I cant really help you with as it can be a pretty complex topic depending on what exactly you want to do
     
  15. TAPE_EATER

    TAPE_EATER

    Joined:
    Nov 2, 2019
    Posts:
    15
    So it's pretty much the final cast to see if the motor can move there.
    I put it in now, and it actually works allright with the given position of the casts (placing the character on top of the object to climb), i was setting the hang position offset wrong and it didn't work on all angles/positions. So i have to still figure out what the best way is to set the offset from the ledge.

    Thanks for clarifying
     
    Vincent454 likes this.
  16. jmgek

    jmgek

    Joined:
    Dec 9, 2012
    Posts:
    177
    Does, anyone have a clean way to handle enemy targeting? Just need the controller to move a few feet to the target and rotate towards the target to handle some of the animation issues we're having with a hack and slash game.
     
    tonyomendoza likes this.
  17. Mirath

    Mirath

    Joined:
    Aug 5, 2012
    Posts:
    14
    Hiya, did you ever figure out the cause of this? Currently dealing with the same and would like to figure out what to change to have it behave more consistently.
     
  18. rafaelcraftero_unity

    rafaelcraftero_unity

    Joined:
    Jun 30, 2020
    Posts:
    8
    Hi everyone, i've been struggling with the kcc because when im jumping and it hits the ceiling it immediately stop the momentum and goes down and i need it to doesn't happen, do you know how to do it?
     
  19. TAPE_EATER

    TAPE_EATER

    Joined:
    Nov 2, 2019
    Posts:
    15
    I have tried a couple of ways to add extra velocity for a launchpad based on the example scenes. But it seems that the velocity that's added is not consistent with the different states the character can be in. For instance when I jump on a launchpad it bounces the player up only a small fraction of the velocity the player gets entering the launchpad hitbox when grounded even though I am setting the current velocity to Vector3.zero before adding the extra velocity with Character.AddVelocity(Vector3.up * 50f).


    So not jumping and walking into the hitbox will add the velocity like expected and continues to work every consecutive landing on the hitbox, but landing in the hitbox from a jumping state (having pressed the jump button) will dampen the velocity to almost no bounce at all and will not be a consistent amount of movement each time.


    Does anyone have any pointers for getting consistent and stable velocity impulses like this?
     
  20. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    281
    Hi, I wanna know if you guys let a lot of enemies using Motor?
    The Motor of KCC is a robust system to handle movement, but look at it, multi thousands of lines of code. Is it good to use for multiple enemies rather than the main character?
    If you don't use it, can suggest any system for enemies' movement thanks!
     
  21. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    It runs surprisingly well actually, but it of course depends on how many enemies your game has. You can check how much processing time it takes in the profiler with deep profile enabled. I would also check if your enemies even need to have physics enabled, if you just have them move on the navmesh without physics, that will be the fastest.
     
  22. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    281
    That is be great option. thanks for pointing out. I'm currently inspecting Flock Box DOTs. It looks like it covers lots of use cases. Can suit my needs.
     
    Vincent454 likes this.
  23. rafaelcraftero_unity

    rafaelcraftero_unity

    Joined:
    Jun 30, 2020
    Posts:
    8
    Could anyone help me?
     
  24. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    I havent tried this but maybe there is some code that adds velocity downwards if a collision is detected above the player whilst hes not grounded and going up, just remove that code and it might work, but I am not sure (If there is, it should be in the motor script)
     
  25. chris73it

    chris73it

    Joined:
    Oct 15, 2013
    Posts:
    21
    Hi, I would like to join the Discord community, but I cannot find the link anywhere. If it exists, I would like to know what is the special shake to enter this exclusive club :) Thank you!
     
  26. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    281
    My character sometimes be launched at too much force, especially in contacts with lots of ragdoll colliders from other character, or sliding off a ledge.
    launching at neck-break speed looks fun but not easy on controlling gameplay.
    Do any one handle this?

    I tried limit air speed in UpdateVelocity method, but got no luck
    Code (CSharp):
    1.                                 //limit air move spd
    2.                                 var clampedMagnitude = math.clamp(currentVelocity.magnitude, 0, math.max(MaxAirMoveSpeed, JumpUpSpeed));
    3.                                 currentVelocity = currentVelocity.normalized * clampedMagnitude;
    4.                             }
    Obviously, this code tries limit speed to air spd and jump spd, it will not cover the case where character launched by attacks. But I'll handle that later, currently I want to limit speed when character launched unintended.
     
  27. raykingqd

    raykingqd

    Joined:
    Feb 11, 2020
    Posts:
    1
    unity2022 no longer supports setting Rigidbody.velocity and angularVelocity directly. how can I solve this problem?
    Code (CSharp):
    1. Setting angular velocity of a kinematic body is not supported.
    2. UnityEngine.Rigidbody:set_angularVelocity (UnityEngine.Vector3)
    3. KinematicCharacterController.PhysicsMover:VelocityUpdate (single) (at Assets/KinematicCharacterController/Core/PhysicsMover.cs:249)
    4. KinematicCharacterController.KinematicCharacterSystem:Simulate (single,System.Collections.Generic.List`1<KinematicCharacterController.KinematicCharacterMotor>,System.Collections.Generic.List`1<KinematicCharacterController.PhysicsMover>) (at Assets/KinematicCharacterController/Core/KinematicCharacterSystem.cs:192)
    5. KinematicCharacterController.KinematicCharacterSystem:FixedUpdate () (at Assets/KinematicCharacterController/Core/KinematicCharacterSystem.cs:134)
    6.  
     
  28. slonersoft

    slonersoft

    Joined:
    Feb 7, 2015
    Posts:
    11
    I’m having an issue where creating an NPC with a motor via Instantiate causes the NPC to appear in a different location near the origin for one frame. Anyone seen this before? I removed all functionality from the component and discovered it was KinematicCharacterMotor.

    Does @philsa-unity still support this package?
     
  29. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    281
    @slonersoft
    Don't ping him like this bro, he's now a Unity dev, got hands full now.
    This package is now handed to community, we support ourselves.

    Regarding your problem, you can always teleport motor to your desire position using Motor.SetPositionAndRotation(position, rotation);
     
    Gooren likes this.
  30. slonersoft

    slonersoft

    Joined:
    Feb 7, 2015
    Posts:
    11
    @Spikebor I see he's got an ECS version he's developing internal to Unity, so I'm gonna see about switching to that. For now, your fix works great for me. Thanks!

    I didn't even notice the _unity on his username at first. I wrote it in, saw his avatar was the same, and auto-completed what it gave me. Congrats to him! He makes good software.
     
    Last edited: Mar 27, 2023
    Gooren and Spikebor like this.
  31. kana1939

    kana1939

    Joined:
    Jan 4, 2022
    Posts:
    13
    I implemented jumping using state and ForceUnground, but I don't want the alignment to the ground feature. Can I disable it separately?
     
  32. fjf1889

    fjf1889

    Joined:
    Oct 30, 2021
    Posts:
    2
    animation driven rootmotion jump. I cant controll the y axis movement by animation. Can any one help how can i implement it? I use this code in UpdateVelocity(): currentVelocity = _rootMotionPositionDelta / deltaTime.but It doesn't work very well.(i doesn't bake Y)
     
  33. alexanderFabula

    alexanderFabula

    Joined:
    Sep 1, 2019
    Posts:
    22
    Im also looking for a solution where I can apply the velocity of moving platforms moved by PhysicsMover (in a timeline) to the character when they are climbing on a ladder attached to a moving platform.
     
  34. brummer

    brummer

    Joined:
    Jul 3, 2013
    Posts:
    31
    Has anyone ran into this issue before?
    I'm copying the same code between two projects, and on one of them, it seems like the controller's collider's position does not match the position of the motor of the transform, when debugged.
    Which is weird, because in the editor view, the collider does indeed seem to be in the correct place.
    Nothing fancy is being done, it's pretty basic code relative to the examples without any in-depth modification.
    Seems like the collider's position is just staying where it is at the start, and if velocity is applied to the controller, the motor and transform moves, but the collider stays in the same position when debugged with bounds.center. They're all on the same transform.
     
  35. Blepius

    Blepius

    Joined:
    Mar 9, 2021
    Posts:
    68
    I'm able to get my character stuck in the falling state on wedged floors (image for reference). Motor.GroundingStatus.FoundAnyGround is returning false in the attached image.

    Has anyone encountered this before? I'm completely stumped, and this is commonly encountered.

    Edit: Progress!!

    After diving a bit into the motor script, I think I see part of the issue here,
    • ProbeGround returns false in this scenario.
    • ProbeGround should find ground since gravity is enabled, and for the purpose of this test, I made gravity an enormous acceleration. The player should fall and collide with the ground.
    But that doesn't happen.

    However, InternalCharacterMove is working and I can apply air movement here. By increasing my air acceleration, my player is now able to bump into the sides, which causes Motor.GroundingStatus.FoundAnyGround to come back true, freeing the character.

    I do think this counts as a bug, though, since not all characters will/should have air acceleration, and those without it will fall into geometry like this.
     

    Attached Files:

    Last edited: Jun 13, 2023
    Rusted_Games likes this.
  36. Blepius

    Blepius

    Joined:
    Mar 9, 2021
    Posts:
    68
    After more testing, I've realized that this is kind of a problem if our players have 0 air acceleration.

    I've reproduced this in the Character Playground scene. All that needs to be done to the default testing scene is to create a wedge shape (as in my attached image), then set air acceleration on the player to 0.

    The player becomes suspended in air and is unable to detect any ground at all. This happens after pressing jump inside the wedge.

    Gravity is unable to restore a connection, though horizontal air acceleration does restore a connection to ground by forcing a side collision.

    I'm really stumped here as I don't see a way to avoid this other than to hack something in. If anyone has any ideas, I'll give them a try!
     

    Attached Files:

    Last edited: Jun 17, 2023
  37. OrangeJuice224

    OrangeJuice224

    Joined:
    Jul 5, 2023
    Posts:
    9
    Hi everyone,

    I've just download the Kinematic Character Controller:
    https://assetstore.unity.com/packages/tools/physics/kinematic-character-controller-99131

    I opened this scene here:
    Assets \ KinematicCharacterController \ Examples \ Scenes \ CharacterPlayground

    I changed in the Hierarchy:
    (changed from Kinematic to None)
    ExampleCharacter -> Rigidbody interaction Settings -> Rigidbody Interaction Type: None

    I added a simple sphere (with default collider), scaled the sphere to (X: 2, Y:2, Z:2) and attached a default rigidbody component to it.

    E.g. now when I jump on the left corner of the sphere, then the sphere moves to right. It looks not correct.
    Why it's not moving to the left.

    Here is an exmaple video. Camera orthographic view.
    https://imgur.com/5UVkWOY

    Thanks for any help!
     
  38. JohnyBroo

    JohnyBroo

    Joined:
    Dec 30, 2021
    Posts:
    1
    Hello, I think I need this for my game but I can't figure out how to setup it, can someone explain me this more precisely ?
     
  39. Kev00

    Kev00

    Joined:
    Dec 6, 2016
    Posts:
    229
    Quick question what is the best way to ensure that the capsule collider follows the character's animation orientation when a character dies? In other words, the character plays the dead animation but the capsule remains upright. Is it typically a mater of disabled the controller or rotating the capsule collider along the ground?
     
  40. tconkling

    tconkling

    Joined:
    Jul 13, 2012
    Posts:
    20
    @Kev00 - when the character is dead, it probably makes sense to disable the character controller. (They're likely not going to be locomoting around - except maybe in response to physics events, in which case you'd want your colliders to be non-kinematic anyway)
     
    Kev00 likes this.
  41. zevonbiebelbrott

    zevonbiebelbrott

    Joined:
    Feb 14, 2021
    Posts:
    122
    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.
     
  42. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    There actually is, I don't remeber what the variable was called though, but maybe it was something like air velocity control
     
    zevonbiebelbrott likes this.
  43. zevonbiebelbrott

    zevonbiebelbrott

    Joined:
    Feb 14, 2021
    Posts:
    122

    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...
     
  44. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    I think there is a setting to limit air speed, maybe limit it to the same value as movement speed
     
  45. PixelDough

    PixelDough

    Joined:
    Apr 27, 2018
    Posts:
    56
    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
     
  46. VirtualDestructor

    VirtualDestructor

    Joined:
    May 3, 2014
    Posts:
    44
    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().

    Code (CSharp):
    1. private void OnDisable()
    2. {
    3.    // begin bug fix
    4.    Velocity = Vector3.zero;
    5.    AngularVelocity = Vector3.zero;
    6.    // end bug fix
    7.  
    8.    KinematicCharacterSystem.UnregisterPhysicsMover(this);
    9. }
     
    socialtrens and halley like this.
  47. VirtualDestructor

    VirtualDestructor

    Joined:
    May 3, 2014
    Posts:
    44
    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"
     
    Last edited: Dec 12, 2023
  48. tapyourashley

    tapyourashley

    Joined:
    Jan 10, 2021
    Posts:
    1
    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
     
  49. Furgon13

    Furgon13

    Joined:
    Jun 5, 2018
    Posts:
    2
    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?
     
  50. Yggdrazyl

    Yggdrazyl

    Joined:
    Jul 12, 2017
    Posts:
    16
    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.