Search Unity

[Released] Kinematic Character Controller

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

  1. RazT

    RazT

    Joined:
    Feb 7, 2019
    Posts:
    15
    Hi 2 all!

    Does anybody know, how to decouple the camera for VR?

    To achieve an effect like in the game MOSS VR:
    - one scene camera, being the plyers VR head/eyes

    I've tried to make something but failed and would be gratefull to gt some help.

    Thank you all for your help!
     
  2. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    20
    @Hannibal_Leo I've been having issues setting up my own state machine with this asset. Would it be possible to elaborate more on your method?
     
  3. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    Sure.

    Ok so the CharacterController (FPS Controller in my case) get's all the calls from the KinematicCharacterMotor, such as:

    Code (CSharp):
    1. public void SetInputs(ref PlayerCharacterInputs inputs)
    2.  
    3. public void BeforeCharacterUpdate(float deltaTime)
    4.  
    5. public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
    6.  
    7. public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
    And so on..

    If you write your code directly inside this class, it will get really messy soon.
    So I decided, to not have any code there, but pass it further down instead.

    so my calls look like this:
    Code (CSharp):
    1. public void SetInputs(ref PlayerCharacterInputs inputs)
    2.         {
    3.             CurrentCharacterState.SetInputs(ref inputs);
    4.         }
    5.  
    6. public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
    7.         {
    8.             CurrentCharacterState.UpdateRotation(ref currentRotation, deltaTime);
    9.         }
    Also, which is unusual for a statemachine, the FPS Controller switches states. Usually the states would do that themselfs.

    Looks like this:

    Code (CSharp):
    1. public void PostGroundingUpdate(float deltaTime)
    2.         {
    3.             CurrentCharacterState.PostGroundingUpdate(deltaTime);
    4.  
    5.             if (motor.GroundingStatus.IsStableOnGround && CurrentCharacterState == airborneState)
    6.             {
    7.                 TransitionToState(defaultState);
    8.             }
    9.             else if (!motor.GroundingStatus.IsStableOnGround && CurrentCharacterState == defaultState)
    10.             {
    11.                 TransitionToState(airborneState);
    12.             }
    13.         }
    Transition to state code is pretty simple.

    Code (CSharp):
    1.         public void TransitionToState(FPSCharacterStateBase newState)
    2.         {
    3.             if (CurrentCharacterState == newState) return;
    4.  
    5.             FPSCharacterStateBase tmpInitialState = CurrentCharacterState;
    6.             tmpInitialState.OnStateExit(newState);
    7.             CurrentCharacterState = newState;
    8.             newState.OnStateEnter(tmpInitialState);
    9.         }
    So the FPS Controller only has code to switch between states and to detect which state should be updated.

    The states just have OnStateEnter, OnStateExit and forward their calls further down to the abilities, which looks like this:

    Code (CSharp):
    1. public abstract class FPSCharacterStateBase : MonoBehaviour
    2.     {
    3.         [HideInInspector]
    4.         public KinematicCharacterMotor motor;
    5.         public List<FPSCharacterAbilityBase> activeAbilities = new List<FPSCharacterAbilityBase>();
    6.  
    7.         private void Awake()
    8.         {
    9.             motor = GetComponentInParent<KinematicCharacterMotor>();
    10.         }
    11.  
    12.         /// <summary>
    13.         /// Event when entering a state
    14.         /// </summary>
    15.         public virtual void OnStateEnter(FPSCharacterStateBase fromState)
    16.         {
    17.             foreach(FPSCharacterAbilityBase ability in activeAbilities)
    18.             {
    19.                 if (!fromState.activeAbilities.Contains(ability))
    20.                 {
    21.                     ability.OnStart();
    22.                 }
    23.             }
    24.         }
    25.  
    26.         /// <summary>
    27.         /// Event when exiting a state
    28.         /// </summary>
    29.         public virtual void OnStateExit(FPSCharacterStateBase toState)
    30.         {
    31.             foreach (FPSCharacterAbilityBase ability in activeAbilities)
    32.             {
    33.                 if (!toState.activeAbilities.Contains(ability))
    34.                 {
    35.                     ability.OnStop();
    36.                 }
    37.             }
    38.         }
    39.        
    40.  
    41.         public virtual void SetInputs(ref PlayerCharacterInputs inputs)
    42.         {
    43.             foreach (FPSCharacterAbilityBase ability in activeAbilities)
    44.             {
    45.                 if (!ability.enabled) continue;
    46.                 ability.SetInputs(ref inputs);
    47.             }
    48.         }
    49.         public virtual void BeforeCharacterUpdate(float deltaTime)
    50.         {
    51.             foreach (FPSCharacterAbilityBase ability in activeAbilities)
    52.             {
    53.                 if (!ability.enabled) continue;
    54.                 ability.BeforeCharacterUpdate(deltaTime);
    55.             }
    56.         }
    57.         public virtual void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
    58.         {
    59.             foreach (FPSCharacterAbilityBase ability in activeAbilities)
    60.             {
    61.                 if (!ability.enabled) continue;
    62.                 ability.UpdateRotation(ref currentRotation, deltaTime);
    63.             }
    64.         }
    for every single call.
    The actual states just look like this:

    Code (CSharp):
    1. public class FPSState_Default : FPSCharacterStateBase
    2.     {
    3.     }
    No code at all. They are just unique classes because I might want to override a method or have something special in the OnStateEnter / OnStateExit methods like in the SwimState:
    Code (CSharp):
    1. public class FPSState_Swim : FPSCharacterStateBase
    2.     {
    3.         public override void OnStateEnter(FPSCharacterStateBase fromState)
    4.         {
    5.             base.OnStateEnter(fromState);
    6.             motor.SetGroundSolvingActivation(false);
    7.         }
    8.         public override void OnStateExit(FPSCharacterStateBase toState)
    9.         {
    10.             base.OnStateExit(toState);
    11.             motor.SetGroundSolvingActivation(true);
    12.         }
    13.     }
    And inside the Abilities, there is the actual code that gets executed, like so:
    Code (CSharp):
    1. public class FPSAbility_Sprint : FPSCharacterAbilityBase
    2.     {
    3.         bool _sprintButtonHeld;
    4.         bool _isCrouching;
    5.  
    6.         public override void SetInputs(ref PlayerCharacterInputs inputs)
    7.         {
    8.             _sprintButtonHeld = inputs.SprintHeld;
    9.             _isCrouching = shared.isCrouching;
    10.  
    11.             shared.isSprinting = _sprintButtonHeld && !_isCrouching;
    12.         }
    13.     }
    This isn't a perfect solution at all, but I am pretty happy with it. Each ability can focus on just one thing. Walking, Jumping, Sprinting, Swimming, Flying and so on. I can add new Abilities easily and they will get updated when they are assigned to a state that is active right now.
    There is no jumping or crouching in the swim state, those abilities won't get executed when the character is in Water.

    So basically, I just moved the code out of the FPS Controller and spread it across small classes with just one purpose (just jumping, just sprinting, ..).
     
    Kuuo likes this.
  4. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    20
    Thank you for the explanation. Had hoped to see similarities in my approach so I could potentially find out why my jumping doesn't work when switching between grounded and airborne. I think your approach is quite different from mine but I will look into your ability system as that may help me.
     
  5. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    I had the same problem with jumping. It's because a variable is set, when the player isn't grounded but at that time, the "jumping" code doesn't get an update anymore.
    I fixed that by having an "Exit" method called
    OnStop()
    . Because I can be sure the character isn't grounded, when the state "Default" isn't the current state, wether it's swimming, airborne or flying, he isn't grounded.

    Then I set the variable and everything works as it should.
     
  6. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    20
    Oh I see that makes sense. I'm not entirely sure that's my issue. I would exit my grounded/default state with a velocity of (0,10,0) but when I enter the airborne state and start the updateVelocity method it would be a different value(negative already).

    Which of your classes covers the actual movement and update code from the walkthrough?Is it in the abilities, the states? The example you showed looked like it would be in the abilities but the abilities only showed taking SetInput. Do you call setInput of each ability then when updateVelocity gets called you call that of each ability and so on?

    With everything segregated as so wouldn't it be no different than if the abilities were the individual classes?
    You have default which does walk jump crouch and sprint. Can those not each be individual states?
     
  7. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    All calls are forwarded downwards to the ability, I can just choose which one I want to use:

    Code (CSharp):
    1. public abstract class FPSCharacterAbilityBase : MonoBehaviour
    2. {
    3.     public KinematicCharacterMotor motor;
    4.     public FPSControllerShared shared;
    5.  
    6.     protected virtual void Awake()
    7.     {
    8.         motor = GetComponentInParent<KinematicCharacterMotor>();
    9.         shared = GetComponentInParent<FPSControllerShared>();
    10.     }
    11.  
    12.     private void Start()
    13.     {
    14.         // start method to get enabled toggle in inspector
    15.     }
    16.  
    17.     /// <summary>
    18.     /// executed when we switch from a state that does not have the ability
    19.     /// to a state that has the ability
    20.     /// </summary>
    21.     public virtual void OnStart() { }
    22.     /// <summary>
    23.     /// executed when we switch from a state that has the ability
    24.     /// to a state that does not have the ability
    25.     /// </summary>
    26.     public virtual void OnStop() { }
    27.  
    28.     public virtual void SetInputs(ref PlayerCharacterInputs inputs) { }
    29.     public virtual void BeforeCharacterUpdate(float deltaTime) { }
    30.     public virtual void UpdateRotation(ref Quaternion currentRotation, float deltaTime) { }
    31.     public virtual void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime) { }
    32.     public virtual void AfterCharacterUpdate(float deltaTime) { }
    33.     public virtual void OnGroundHit(Collider hitCollider, Vector3 hitNormal,
    34.         Vector3 hitPoint, ref HitStabilityReport hitStabilityReport) { }
    35.     public virtual void OnMovementHit(Collider hitCollider, Vector3 hitNormal,
    36.         Vector3 hitPoint, ref HitStabilityReport hitStabilityReport) { }
    37.     public virtual void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
    38.         Vector3 atCharacterPosition, Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport) { }
    39.     public virtual void PostGroundingUpdate(float deltaTime) { }
    40.     public virtual void OnDiscreteCollisionDetected(Collider hitCollider) { }
    41. }
    Yes Sprint and Crouch could probably be their own specific state, but in my system, it wouldn't change anything.
    Sprinting and Crouching both set values for other classes to read, so I can increase or decrease the move speed.
    "FPSControllerShared" holds those values (as well as Gravity value and a few other things that are shared across abilities.
     
  8. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    20
    Thanks a lot. This actually helped me get my state machine cleaner and in a better working order.
     
    John_Leorid likes this.
  9. mcguinnessdr

    mcguinnessdr

    Joined:
    Sep 20, 2014
    Posts:
    26
    Hi, trying to solve a problem with the landing position for a character running off a ramp being very inconsistent. It seems that the `groundHitStabilityReport.OuterNormal` being different depending on distance from the ledge is causing this. I assume it's treating the edge of the ledge as if it's nearly flat ground, so the player has velocity as if they were running off a nearly flat surface and not off an upward slope. In the first image you can see cubes that show the start and landing positions. Slightly different start positions on the right lead to very different landing positions on the left. In the second image you can see the `OuterNormal`, how it becomes more vertical the closer the ledge the player is.
     

    Attached Files:

    iceb_ likes this.
  10. iceb_

    iceb_

    Joined:
    Nov 10, 2015
    Posts:
    95
    I am getting similar inconsistent results too when walking off ledges, the landing distance differ quite a bit, and I increase the run speed, and lower FPS to really make it obvious in testing, from both the demo and custom levels. If I set "additional ground check distance" to negative 5 then it becomes consistent, but then the character gets all floaty when walking around. Hope @PhilSA will have some ideas on how to fix this, thanks!!!
     
  11. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    Hi,

    I can confirm this is indeed a problem. Allow me a few days and I think I can at least come up with a fix that I can post in here (and then later I'll update KCC on the store with that fix)

    The fix I have in mind is essentially the same as what I've done to solve this problem in my DOTS character controller asset. I'll just need to find a bit of free time to write a monobehaviour equivalent of this approach
     
    Vincent454 and iceb_ like this.
  12. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    229
    Hey @PhilSA I sent you an email, but I thought I should reach out here as well. I was wondering if it is possible for two of your character controllers to apply forces to each other (one can push the other and vice versa). I have been trying in the demo scene and it doesn't seem to be possible. I haven't seen it mentioned anywhere also. If it is possible, what setup is required to make it so?

    If not, would this be something that is possible to add? I am hoping to have a multiplayer game where characters are able to push each other around. For example, if one character is blocking a doorway, it is very undesirable to be unable to push it out of the way.

    Also, unrelated to above, I see in KinematicCharacterSystem.FixedUpdate() that Time.deltaTime is used for things like gravity. Shouldn't Time.fixedDeltaTime be used there? I noticed as the gravity was not as strong as I expected it to be, and the object did not fall at the rate of Rigidbodies with the default gravity of -9.81.

    Please let me know. Thanks.
     
    Last edited: Nov 5, 2021
  13. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    This is something that would have to be added manually. In your OnMovementHit callback, if there is a KinematicCharacterMotor component on the hit object, you would add a push velocity to that character's KinematicCharacterMotor.BaseVelocity

    This is a very little-known thing, but whenever anything is called during FixedUpdate, the Time.deltaTime value is equal to the fixedDeltaTime
     
    Vincent454 likes this.
  14. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    229
    Thanks for your response, and you're right, I didn't know that, I must have changed another setting at the same time to get the gravity working as expected.

    Just to clarify, by "push" I meant just moving forward into the other character's location.

    As for using OnMovementHit to add a push velocity, would you be willing to make add that to the walkthrough or give an example of how that would look? This seems like a fairly common use case/scenario, I'd be surprised if I'm the first to ask about it. There do seem to be many variables involved though. For example, if both characters are moving side by side, but touching, I wouldn't want to add their velocities together.

    This is my first thought, but it doesn't seem to work too well:

    Code (CSharp):
    1. KinematicCharacterMotor hitKinematicCharacterMotor = hitCollider.GetComponent<KinematicCharacterMotor>();
    2. if (hitKinematicCharacterMotor != null)
    3. {
    4.     Vector3 hitKinematicCharacterMotorVelocity = hitKinematicCharacterMotor.Velocity;
    5.     AddVelocity(hitKinematicCharacterMotorVelocity * Mathf.Clamp01(Vector3.Dot(hitKinematicCharacterMotorVelocity.normalized, hitNormal)));
    6. }
     
    Last edited: Nov 9, 2021
  15. Blepius

    Blepius

    Joined:
    Mar 9, 2021
    Posts:
    68
    Hello!

    I found some weird behavior with some weird geometry. I've attached a gif since I probably couldn't describe it (Note: I'm not pressing jump!)

    Any ideas what I could do to help smooth over this gap? The controller is mostly just what is used in the examples. I've put an audio source on the player here, which plays a noise OnGroundHit. Can't hear it in the gif of course, but my first time over the gap, it is triggered many times.

    Also I've put googly eyes on the controller, because they are funny.



    Edit: Here's another picture to help show that the gap isn't really a raised edge, just a small gap.

     
    Last edited: Nov 9, 2021
    Vincent454 likes this.
  16. SlimeQ

    SlimeQ

    Joined:
    Dec 4, 2018
    Posts:
    3
    I just updated from the original package to the new one, and now my character is getting a ton of choppiness when looking around. I'm assuming this has to do with late updates but from what I can tell it should already be correct.

    What changed?
     
  17. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    I have this problem too every now and then. It doesn't really happen consistently, but when you have very small gaps or really small steps (I think the step is the problem not the gap) like this it can happen. If its possible and not a lot of work I would like to see a fix or workaround maybe
     
  18. gg_michael

    gg_michael

    Joined:
    Sep 24, 2012
    Posts:
    73
    Awesome asset, perfect for integration into different architectures. Thank you!

    Shooting from the hip with a possible dumb question: the motor clearly enforces capsules as needing to be vertical. Judging from the collision logic I assume it is not feasible to have the capsule collider be horizontal? Just thinking about how to adapt the kcc to "longer" entities, such as a horse or a prone humanoid. Logically having a horizontal capsule would make more sense than a vertical capsule for those situations, but I get the distinct impression this package was not made to support such scenarios. Are "horse controllers" typically not kinematic then, or is a horizontal capsule just that different in terms of collision logic?

    Thanks again, great asset!
     
  19. SlimeQ

    SlimeQ

    Joined:
    Dec 4, 2018
    Posts:
    3
    I got an index out of bounds error on this line:


    Code (CSharp):
    1.             // Character controller update phase 1
    2.             for (int i = 0; i < characterMotorsCount; i++)
    3.             {
    4.                 motors[i].UpdatePhase1(deltaTime);
    5.             }
    I'm not really sure how this is possible, since characterMotorsCount should just be equal to motors.Count.

    Edit: I think this has something to do with the character being killed (and so the motor being destroyed) in BeforeCharacterUpdate.
     
    Last edited: Nov 12, 2021
  20. iceb_

    iceb_

    Joined:
    Nov 10, 2015
    Posts:
    95
    bump!
     
    Nothke likes this.
  21. V4LK

    V4LK

    Joined:
    Aug 5, 2020
    Posts:
    4
    Hi,

    I am Currently working on a Game with a Lot of Physics(Like Rocks rolling down a Hill) and I Wondered if I can give external feedback to the player like a Dynamic rb. I know theres a function called HandleSimulatedRigidbodyInteraction but i dont know if that is what Im searching for and how to use it
     
    Last edited: Nov 20, 2021
  22. Chrispins

    Chrispins

    Joined:
    Dec 9, 2014
    Posts:
    15
    Quick question to those of you who already own this asset:

    Is it simple enough to code in a way for moving rigidbodies to 'carry' the character controller even while they aren't touching? For example, via an on/off 'carried' state for the player? This would ideally keep the player from flinging off of an accelerating object even while jumping.
     
  23. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Hello,

    a) Wondering if there is an easy way to make the character slide while on ice material
    b) and get boost while on a speed / boost material
     
  24. gg_michael

    gg_michael

    Joined:
    Sep 24, 2012
    Posts:
    73
    Similar behavior is already included in the example controller - when standing on a moving rigid body (that has the PhysicsMover script attached) the character's momentum will correctly respond. If you needed additional related functionality it would certainly be possible.
     
    Chrispins likes this.
  25. bibbisaurus

    bibbisaurus

    Joined:
    Nov 11, 2021
    Posts:
    7
    Hiya. Bought this asset yesterday, seems really well done. Going through the walkthrough I noticed a minor bug: there is a block of code needlessly repeated in ExampleCharacterCamera.cs.
    Screen Shot 2021-11-19 at 9.32.20 AM.png
     
    vplampinen and Blepius like this.
  26. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    229
    I know it isn't an answer, but maybe you'll find this interesting (look at 45:50):

     
  27. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    229
    I believe so. You can specify an "attached rigidbody override" which will transfer the velocity and angular velocity of said "attached rigidbody" to the character controller. They do not have to be touching.
     
    Chrispins likes this.
  28. Cratesmith

    Cratesmith

    Joined:
    Aug 14, 2011
    Posts:
    137
    I've been using this asset for some prototyping for some 3d platforming, and it solves a lot of problems.

    However because it explicitly uses a single cylinder characters tend to slip off the edges of platforms as if they were slopes... rather than being able to walk to the edge then fall (pretty standard for 3rd person platformers).

    Is there an easy way to do this with the asset? I went through the examples and docs and this didn't seem to be mentioned which seemed a bit odd as far harder problems have been solved.

    I'm not totally stuck if not... I've written my own character controllers before so I'm confident enough to dig in and modify the code to do this, it's just going to be a fair bit of work and I expected that this would be a solved problem.
     
    julekkluczak likes this.
  29. gg_michael

    gg_michael

    Joined:
    Sep 24, 2012
    Posts:
    73
    I know, the dots controller looks so good :eek: but I'm not in a position to overhaul my project away from MonoBehaviours. Wondering if there's some kind of equivalent in this KCC
     
  30. bibbisaurus

    bibbisaurus

    Joined:
    Nov 11, 2021
    Posts:
    7
    @PhilSA In the CharacterPlayground when I run into the AI capsule or a moving platform I get an
    OnMovementHit callback, but when I'm standing still and they hit me I don't seem to get anything. I expected
    OnDiscreteCollisionDetected to be called but it doesn't. Is this expected? How can I know when something else hit me when I'm not moving at all?
     
  31. Paul_Hughes

    Paul_Hughes

    Joined:
    Sep 6, 2018
    Posts:
    33
    Would love to see a zelda and mario type controller. I usually use the Standard Assets FPCtrl or TPCtrl, and have now moved onto the starter assets TPCtrl with touch using the joystick, having trouble implementing sliding on the terrain, my game depends largely on this to work, but since I updated to the new inout system and starter assets joystick I am struggling badly, spending weeks on things like sliding down a steep slope as the player can just jump all the way up the mountain skipping 3/4 of the level and blocking doesn't work as it's in the way of other objects. I really wish Unity had this built in like the old character motor script, it seems ever since 2019.3 there has been a ton of trouble and my eyes are now gazing towards UE5 for the future, yes my programming could be better on the maths/physics side but as an indie dev I can do everything all the time as it's not feasible to make income that way, only bit by bit( pardon the pun lol) do I learn and now since returning in 2017 as I first started with Unity in 2011/12 I am getting there, my background is in C/Assembly/Verilog from Uni so am obviously missing quite a bit in regards to Game Development as a profession. I really hope the Unity devs finish up the remote 5 as that has been quite a hard hit not testing on the remote 5 for the android app as the builds take over an hr and just to test a simple jump it's again just not worth the time. Unity seems to have more on the graphics front i.e. shader graph, vfx graph and now bolt etc for visual scripting for the artists and UE guys, which is all good but don't forget the ones who have been building apps for the better part of a decade and like stability and familiarity not new scripts that make things more difficult.
     
  32. iceb_

    iceb_

    Joined:
    Nov 10, 2015
    Posts:
    95
    hey @PhilSA any updates on updating the KCC movement consistency fix from the DOTS version? Thanks!
     
    Vincent454 likes this.
  33. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Can anyone help with:

    1. Creating a state that makes the player 'slide' as if on ice.

    2. Make the player rotate via A, D instead of mouse look with the camera.

    Thank you
     
  34. Osteel

    Osteel

    Joined:
    Jan 17, 2014
    Posts:
    59
    Hi,

    Loving this asset, and have been making great progress on my latest character controller. I was wondering if there was some documentation I missed that went into the details of what the different structs and properties actually do? Things like the HitStabilityReport.InnerNormal for example.

    Thanks. :)
     
  35. ddule

    ddule

    Joined:
    Sep 9, 2017
    Posts:
    4
    Can someone tell my why is same collision occuring twice? (And how to prevent it)
    I Use OnMovementHit for detecting collision and I apply _internalVelocityAdd push back when collision happens.
    It occurs only when player capsule touches the enemy collider at the corner (cube corner).
    It is important to mention that I have this script:
    Code (CSharp):
    1. public void BeforeCharacterUpdate(float deltaTime)
    2.     {
    3.         Motor.MoveCharacter(Motor.transform.position+MovementVector*deltaTime);
    4.     }
    I am creating physics this way intentionally, I want to seperate velocity from the movement, because my game design is planned that way. The practical result should be when you're e.g pushed from enemy , that you would be still be able to control position without interrupting the velocity.

    The problem is that when I touch enemy at the corner it applies force twice, making player go much further than intended.
     
    Last edited: Dec 1, 2021
  36. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Another follow up question if anyone can help out, I'd like to make the camera rotate with the player (when orientation method is set towards movement) I then disable camera free look.

    In the camera there is an option Rotate with Physics Mover, can anyone help out with the code to have something similar for Rotate With Player;

    I am assuming it has to go somewhere in the HandleCameraInput

    I can do something like
    if(can_CamFreeLook)
    {
    // old code here
    }
    else
    {
    CharacterCamera.PlanarDirection = Character.transform.forward; ?
    }

    This works but I am not sure if its the right approach, and also i'd like to smooth the rotation of the camera as its too fast when the player is turning / walking backwards.

    Thanks
     
  37. Torchinsky

    Torchinsky

    Joined:
    Feb 8, 2014
    Posts:
    17
    Hi there,

    I have an issue with moving platforms controlled by DOTweenAnimation. I wrote simple implementation of IMoveController interface:

    Code (CSharp):
    1. using UnityEngine;
    2. using KinematicCharacterController;
    3.  
    4. [RequireComponent(typeof(PhysicsMover))]
    5. public class TweenMotor : MonoBehaviour, IMoverController
    6. {
    7.     private Vector3 _targetPosition;
    8.     private Quaternion _targetRotation;
    9.     private PhysicsMover _mover;
    10.  
    11.     private void Awake()
    12.     {
    13.         _mover = GetComponent<PhysicsMover>();
    14.         _mover.MoverController = this;
    15.  
    16.         _targetPosition = transform.position;
    17.         _targetRotation = transform.rotation;
    18.     }
    19.  
    20.     public void UpdateMovement(out Vector3 goalPosition, out Quaternion goalRotation, float deltaTime)
    21.     {
    22.         goalPosition = _targetPosition;
    23.         goalRotation = _targetRotation;
    24.     }
    25.  
    26.     // Callback received from tween.onUpdate
    27.     public void UpdateTargetPosition()
    28.     {
    29.         _targetPosition = transform.position;
    30.     }
    31.  
    32.     // Callback received from tween.onUpdate
    33.     public void UpdateTargetRotation()
    34.     {
    35.         _targetRotation = transform.rotation;
    36.     }
    37. }
    The platform moves correctly, the character motor recognises it as AttachedRigidbody, however character doesn't follow it (when platform moves left or right the character stays on the same world position).

    Does anyone know how to properly implement moving platform controlled by DOTweenAnimation? Thanks!
     
  38. jeromeisabelle

    jeromeisabelle

    Joined:
    Aug 29, 2018
    Posts:
    21
    Hi,

    What would be the easiest way to retrieve the contact points and normals in the OnDiscreteCollisionDetected(Collider hitCollider) method? The collision is between the character(capsule) and a concave mesh collider(ex: ProBuilder).

    Thanks!
     
  39. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    I would like to have this too :)
     
    mcguinnessdr and iceb_ like this.
  40. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    How would you prevent this?

    upload_2022-1-10_7-4-54.png

    KinematicCharacterMotor Ledge Settings "Max Stable Distance From Ledge" is not working. (first thing I tried of course)

    But I want more than the character just not being able to stand on those tiny surfaces, I want him to ignore them completely while sliding along the wall (with the user moving towards the wall).

    So basically keeping a distance to the wall at all times.

    How would you approach this? Sending 8 Raycasts every frame, then doing some vector math to set the velocity to keep the distance?
    Or .. doing something in the ground detection itself?

    The same problem applies upwards too of course - he bumps his head, then stops moving. Instead he should slide over these things, not reducing vertical velocity at all.
     
    vplampinen and Vincent454 like this.
  41. TheGamery

    TheGamery

    Joined:
    Oct 14, 2013
    Posts:
    94
    My character is instantiated at runtime, it keeps ending up slightly bellow the floor, if I change any settings on the KinematicCharacterMotor script in runtime it then snaps to correct position.

    Is there a way to fix this?

    Edit (fix): I was altering Capule radius via KinematchCharacterMotor.Capsule.radius, I switched to using SetCapsuleDimensions() and feet are no longer under the floor.
     
    Last edited: Jan 20, 2022
  42. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    20
    How can I create a movable train/tram or ship or space ship vehicle that a Kinematic Character can walk around and another can control.
     
  43. gg_michael

    gg_michael

    Joined:
    Sep 24, 2012
    Posts:
    73
    @PhilSA Interesting discovery regarding KCC on 2022.1 beta:

    It appears this Unity version, or some recently prior version, renders the PhysicsMover and associated logic for moving a character on platforms inoperable. Setting the velocity of a kinematic rigidbody does nothing; as in, the value is not stored in the velocity property. The motor tries to sample this property to calculate moving platform translation, but since it is always 0 the character simply slides off the platform. angularVelocity looks to be the same.

    If you open the playground scene on a fresh 2022.1 project you can see this by trying to jump on one of the blue platforms. I guess a workaround could be to store the "velocity" value in a different property, and sample that from the motor rather than directly reading the rigid body velocity. I did think it kind of odd using rigidbody.velocity on a kinematic rigidbody, but I guess it worked fine up till this version.
     
    Petethegoat likes this.
  44. Ecliptec_Mobile

    Ecliptec_Mobile

    Joined:
    Dec 17, 2017
    Posts:
    33
    I am attempting to use this asset in conjunction with server side physics validation (Bullet physics). I would like to be able to know when the character has moved so that I can cache its position and use a time delta to allow my server-side physics simulation to update its position using the velocity and time delta.

    I tried to send a packet to the server when the user joystick is non-zero (moving). With the packet I assumed a time delta of 0.02f which is the fixed time step which the character motor uses. However, the Client prediction I made using said assumptions does not match up with what the motor produces.

    Is there a way to do this using this package?
     
  45. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    20
    Does this happen in earlier builds because this is the issue I'm having right now. I just assumed I was doing something wrong that's either not explained in the documentation or I missed.
     
  46. gg_michael

    gg_michael

    Joined:
    Sep 24, 2012
    Posts:
    73
    I don't know when exactly this was introduced but it's sometime between 2020.3.18f and the latest 2022.1 beta. The playground scene is fine on the earlier version; upgrade the project without doing anything else and now the character doesn't stick to moving platforms. Very strange. Not sure if it's a new Unity bug or an intentional change.
     
  47. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    20
    Yup, I'm on 2020.3.23f well that's disappointing. I've been trying different things and had no idea guess I should downgrade to 2020.2
     
  48. VirtualDestructor

    VirtualDestructor

    Joined:
    May 3, 2014
    Posts:
    44
    The playground scene works fine for me on version 2020.3.26f1.
     
  49. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    Hi all, little progress update on several issues mentioned recently. I'm wrapping up version 3.4.3 which will contain the following:
    • Take center of mass into account when KCC is standing on a dynamic rigidbody
    • Fixed the PhysicsMover issue in 2022.1beta, where characters couldn't stand on platforms anymore (the issue was caused by the fact that PhysicsMovers used the rigidbody.velocity field, which is not allowed anymore. They now store their velocity independently)
    • Fixed "MaxStableDistanceFromLedge", which wasn't working anymore
    • Fixed faulty ledge normals detection, which lead to unpredictable character trajectories when running off ledges
    Once this is pushed, I will keep investigating a known issue where character degrounding/penetration can sometimes occur on non-convex meshes, and I'll probably push another update soon after just for that fix.
     
    Last edited: Jan 21, 2022
    Blepius, Psyonx, mcguinnessdr and 2 others like this.
  50. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    Thank you so much for continuing to support this so frequently, I could not be happier with this character controller, and so often when playing AAA games I think they should've just used something like this asset haha
     
    PhilSA and Gooren like this.