Search Unity

[Released] Kinematic Character Controller

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

  1. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    I’m getting the
    Code (CSharp):
    1. Character’s lossy scale is not (1,1,1)
    warning. I’m using a Synty character and it and all nested game objects are (1,1,1) except for the ‘Root’ which is scaled to (0.01,0.01,0.01). Bones within the root are (1,1,1). How can I go about fixing this while having my character look the same size (obviously)?
     
  2. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    The character controller should exist at the scene root (not being a child of anything). Any number of scaled objects can be a child of the character controller, serving as its visual representation. So, you can, for example, set the character mesh's transform scale to 0.1 and make it a child of the parentless controller.
     
  3. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    In which case, why am I getting the warning? Not sure what I have to do as my controller is on a game object with no parents and is scaled to 1,1,1.
     
  4. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    You mentioned that the "Root" is scaled to 0.1. If this is a child object nested under the controller object (rather than being the actual character root) and the controller object's parent and scale aren't changed at runtime either, I'm not sure what the cause could be.
     
  5. desukarhu

    desukarhu

    Joined:
    Jun 14, 2017
    Posts:
    27
    Hi!

    Sorry for a super basic question, but I just cant get this to work.

    Using ExampleCharacterController as a base, how would I continously rotate my character around with horizontal input keys? As in, I don't want horizontal keys to apply any movement. Only to make the character spin around in place slowly. Instead of (like how it works now) rotating character to face left or right and moving in that direction.
     
  6. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    Override the UpdateRotation function. Search for it in the included user guide PDF for details. For the rotation calculation itself, look up Quaternion rotation in the Unity docs.
     
  7. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    Theres a bug in the examples, if you crouch and go in the water, it stuck in crouch state.
     
  8. Ruufer

    Ruufer

    Joined:
    Jul 28, 2016
    Posts:
    17
    hey guys, for some reason I can only turn AutoSimulate "off" if I call it every frame.
    Simply setting it at start or awake does not work. in other words...

    this works
    Code (CSharp):
    1.     void FixedUpdate()
    2.     {
    3.         KinematicCharacterSystem.Settings.AutoSimulation = false;
    4.         KinematicCharacterSystem.Simulate(Time.fixedDeltaTime, KinematicCharacterSystem.CharacterMotors, KinematicCharacterSystem.PhysicsMovers);
    5.     }

    but this does not:
    Code (CSharp):
    1.     void Start()
    2.     {
    3.         KinematicCharacterSystem.Settings.AutoSimulation = false;
    4.     }
    5.  
    6.     void FixedUpdate()
    7.     {
    8.         KinematicCharacterSystem.Simulate(Time.fixedDeltaTime, KinematicCharacterSystem.CharacterMotors, KinematicCharacterSystem.PhysicsMovers);
    9.     }

    I am baffled as I cannot see anywhere else in code it could be set. any ideas? is there something about KCCSettings that I am missing?
     
  9. keybol23

    keybol23

    Joined:
    Aug 13, 2013
    Posts:
    26
    Does anyone have tried making a Kinematic bullet? Or making a throwable object kinematic using this asset? Hoping for some help on how to start and make it
     
  10. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    Seems to me that using KCC for something that doesn’t require any grounding may be overkill.
     
  11. nindim

    nindim

    Joined:
    Jan 22, 2013
    Posts:
    130
    Hi @PhilSA or anyone else familiar with this controller!

    Most of the time I need two character controllers to bump into one another and stop each others movement, but at other times I need one of the players to kill the other on contact.

    When this collision is detected I disable the killed player's controller allowing the killer to pass through. Unfortunately by this point I assume the controllers have performed their de-penetration logic so even though the killer passes through the killed player, it causes a snag in the movement. In this scenario I woukd like the killer to pass right through the killed player without its velocity being affected, like it was a ghost (but obviously I still need to detect the collision).

    I have managed to remove the snag by doing a complete resimulation of the killer character for that frame, but this seems overkill and there must be a better way?

    I'm also not sure if what I'm doing is correct, for the resimulation I update the single controller AND all the PhysicsMovers, my worry is that the PhysicsMovers have already been updated during the main update loop so I'm doubling up here, is this OK/desired?

    I don't use auto simulation and my main update is done first followed by and necessary single character resimulates.

    Thanks!

    - Main KCC System Update called from Update() -
    Code (CSharp):
    1.  
    2. if (KinematicCharacterSystem.GetInstance() != null)
    3. {
    4.     if (KinematicCharacterSystem.Settings.Interpolate)
    5.     {
    6.         KinematicCharacterSystem.PreSimulationInterpolationUpdate(timeThisStep);
    7.     }
    8.  
    9.     KinematicCharacterSystem.Simulate(timeThisStep, KinematicCharacterSystem.CharacterMotors, KinematicCharacterSystem.PhysicsMovers);
    10.  
    11.     if (KinematicCharacterSystem.Settings.Interpolate)
    12.     {
    13.         KinematicCharacterSystem.PostSimulationInterpolationUpdate(timeThisStep);
    14.     }
    15. }
    16.  

    - Redoing The Character's Movement - Occurs After Main KCC System Update -
    Code (CSharp):
    1.  
    2. private void RedoCharacterMovement(float deltaTime)
    3. {
    4.     m_controller.Motor.ApplyState (m_lastControllerState);
    5.  
    6.     if (KinematicCharacterSystem.Settings.Interpolate)
    7.     {
    8.         KinematicCharacterSystem.PreSimulationInterpolationUpdate(deltaTime);
    9.     }
    10.        
    11.     SimulateCharacter (deltaTime);
    12.  
    13.     if (KinematicCharacterSystem.Settings.Interpolate)
    14.     {
    15.         KinematicCharacterSystem.PostSimulationInterpolationUpdate(deltaTime);
    16.     }
    17. }
    18.  
    19. // Simulates this character (only) and the KinematicCharacterSystem's PhysicsMovers
    20. private void SimulateCharacter(float deltaTime)
    21. {
    22.     List<PhysicsMover> movers = KinematicCharacterSystem.PhysicsMovers;
    23.     int physicsMoversCount = movers.Count;
    24.  
    25.     // Update PhysicsMover velocities
    26.     for (int i = 0; i < physicsMoversCount; i++)
    27.     {
    28.         movers[i].VelocityUpdate(deltaTime);
    29.     }
    30.                
    31.     m_controller.Motor.UpdatePhase1(deltaTime);
    32.  
    33.     // Simulate PhysicsMover displacement
    34.     for (int i = 0; i < physicsMoversCount; i++)
    35.     {
    36.         PhysicsMover mover = movers[i];
    37.  
    38.         mover.Transform.SetPositionAndRotation(mover.TransientPosition, mover.TransientRotation);
    39.         mover.Rigidbody.position = mover.TransientPosition;
    40.         mover.Rigidbody.rotation = mover.TransientRotation;
    41.     }
    42.  
    43.     // Character controller update phase 2 and move
    44.     m_controller.Motor.UpdatePhase2(deltaTime);
    45.     m_controller.Motor.Transform.SetPositionAndRotation(m_controller.Motor.TransientPosition, m_controller.Motor.TransientRotation);
    46.  
    47.     Physics.SyncTransforms();
    48. }
    49.  
     
    Last edited: Feb 13, 2020
  12. Alvarezmd90

    Alvarezmd90

    Joined:
    Jul 21, 2016
    Posts:
    151
    Huh..?! xD
    My character cannot move after a new scene is loaded. And I have it on dontdestroyonload.
    The kinematic motor is causing it because when I disable and re-enable it, it works again.
    Does anybody know what causes this?
     
  13. eastes

    eastes

    Joined:
    Sep 1, 2012
    Posts:
    59
    5 Star asset you have going! Thank you.

    In your examples, the line below bugs me out sometimes. When the character is falling lands, this line of code sometimes takes the Y axis magnitude and distributes it to the X and/or Z axis, launching the player forwards. (this is my current theory) It happens around 1 in 20 jumps or walking of ledges. When I comment it out, my character doesn't appear to be effected.

    Question 1: Can you please help explain what this line does?
    Question 2: Would a potential solution be to Zero out the Y axis? (assuming my theory is correct)

    Code (CSharp):
    1. // Reorient velocity on slope
    2. currentVelocity = Motor.GetDirectionTangentToSurface(currentVelocity, Motor.GroundingStatus.GroundNormal) * currentVelocity.magnitude;
    Edit: I'm not 100% sure if I've broken the script somewhere else, that is leading to this problem.
     
  14. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    Should the Cinemachine Brain be set to Fixed Update or does it not matter? I'm not using any moving platforms, if that makes a diff.
     
  15. Janoooba

    Janoooba

    Joined:
    Feb 9, 2016
    Posts:
    43
    I've had this happen to me if the scene the player is in isn't set to "Active" oddly enough. I also disabled my KCC script until I'm ready to move the player, at which point I enable it through my game logic. Maybe that'll help?

    This line redirects the current velocity along slopes so that you aren't losing velocity when going up or down hill. It projects the current velocity onto the ground plane and normalizes it, then multiplies it by the current magnitude.

    I've never had any issues with this myself, but it does seem plausible that this line could cause a bug if grounding doesn't reset the y velocity before this line runs. Maybe this is a Update vs FixedUpdate mismatch?
     
    Alvarezmd90 likes this.
  16. Alvarezmd90

    Alvarezmd90

    Joined:
    Jul 21, 2016
    Posts:
    151
    Hell yeah. I solved it right now thanks to your comment. :)


    Calling it .15f after loading an new area is unnoticeable because there's a fade in anyway.
     
  17. eastes

    eastes

    Joined:
    Sep 1, 2012
    Posts:
    59
    Thank you, Very helpful. I'm going to look more into the FixedUpdate VS Update mismatch.

    For now, I'm setting y velocity to zero OnGroundHit. Hopefully that does the trick.
     
    Last edited: Feb 20, 2020
  18. Berserker44

    Berserker44

    Joined:
    Sep 1, 2013
    Posts:
    29
    @PhilSA Sorry to bring up a old comment, but I actually wouldn't mind getting access to the older version with the class based FSM as well. I love the fact that you gave an example using a FSM but I hate enum-based state machines. It will take some time for me to refactor the current one, so I thought I could ask.
     
  19. keybol23

    keybol23

    Joined:
    Aug 13, 2013
    Posts:
    26
    It's for throwable object like a barrel or a grenade so I need to have grounding and wall collissions
     
    transat likes this.
  20. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    I'll count this as a bug that I should fix. The KinematicCharacterSystem creates its KCCSettigs when it gets created, and it gets created in the OnEnable() of Motors & PhysicsMovers

    For now though you should be able to turn AutoSimulate off if you put a [DefaultExecutionOrder(100)] on the monobeahaviour where you set this on Start
     
    andreiagmu likes this.
  21. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    I've done something like that in a project (like a soccer ball that could react to explosions and move extremely fast), and I would say it's a good idea

    You can call motor.SetGroundSolvingActivation(false) on your bullet's motor to skip all the ground detection functions, which represents nearly 50% of the performance cost of character updates usually (I'd have to check that to be sure, but I know ground detection was a huge chunk of frame time)
     
    andreiagmu likes this.
  22. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    You could try doing your "kill character" in IsColliderValidForCollisions() instead of OnMovementHit(). Basically the character's movement update does this:
    • while (isMovementRemaining)
      • CapsuleCastAll(movement)
      • iterate on each hit of the capsuleCast and find the closest one where IsColliderValidForCollisions(hit) returns true
      • project velocity on closestHit
      • call OnMovementHit(closestHit)
    So IsColliderValidForCollisions() happens before the velocity of the character has been projected to "bounce off" of the other character
     
  23. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    Sounds like something in your scene might accidentally destroy the KinematicCharacterSystem on start/awake/onEnable?

    When you start the scene, do you see a "KinematicCharacterSystem" gameobject being created, like in the example playground scene?
     
    Last edited: Feb 21, 2020
  24. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    Your theory is correct. I could swear there was code in KinematicCharacterMotor that prevented this but I just checked and I might have accidentally removed it, thinking it was useless.

    The problem happens when the "ground detection" detects that we've just landed on stable ground this frame before the "movement capsuleCasts" do, which is why it happens relatively rarely

    But the "// Reorient velocity on slope" line is still useful to make sure you won't get any velocity loss at all when you detect an upward slope angle change (it's hard to explain)

    For now you can fix the issue by doing this at the very start of your UpdateVelocity(), before anything else is done with the velocity:
    Code (CSharp):
    1. // Handle stable landing
    2.                     if (motor.GroundingStatus.IsStableOnGround && !motor.LastGroundingStatus.IsStableOnGround)
    3.                     {
    4.                         currentVelocity = Vector3.ProjectOnPlane(currentVelocity , motor.CharacterUp);
    5.                         currentVelocity  = motor.GetDirectionTangentToSurface(currentVelocity , motor.GroundingStatus.GroundNormal) * currentVelocity .magnitude;
    6.                     }
    What this code does is that if we detect that we've just landed, we kill the y velocity, preserve the xz velocity, and then reorient that on the slope. All in all this means that when you do a stationary jump on a slope where you're stable, you won't "slide downwards" when you land. And if you do a moving jump that lands on a slope where you're stable, you'll slide downwards but only with the velocity magnitude of what your horizontal movement was

    But I'll add the fix to my todo list
     
    Last edited: Feb 21, 2020
    eastes, andreiagmu and OhiraKyou like this.
  25. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    I don't have it readily available at the moment, but here's an overview of how it could work. This following approach is much better than what I had in the old example anyway, so I wouldn't recommend the old one:
    • You make one ICharacterController implementation per state of your character (StandardState, SwimmingState, DashingState). So each state gets to say what UpdateVelocity() is, what IsColliderValidForCollisions() is, etc...
    • You make "MyCharacterStateManager" (just a regular monobehaviour) that creates a new instance of all these states on Start, saves them as class variables, and assigns motor.CharacterController = myStandardState;
    • In your MyCharacterStateManager's Update, detect state transitions in any way you see fit. And when you want to transition to a swimming state for example, do motor.CharacterController = mySwimmingState;
    • If you need logic to be shared between different states, simply write it as a public function in MyCharacterStateManager, and make your states all call that same function
     
  26. Alvarezmd90

    Alvarezmd90

    Joined:
    Jul 21, 2016
    Posts:
    151
    No, it's actually tagged as DontDestroyOnLoad. Along with other game objects packed into an empy gameobject.
    It's like Janoooba told me, because it's script execution order is causing it to be executed after the new scene has been placed, the kinematic game controller might be on a deactivated gameobject for just a millisecond, causing it to freeze. The freezing then, can only be resolved by disabling and then re-enabling the motor component.
     
  27. mutp

    mutp

    Joined:
    Oct 1, 2018
    Posts:
    79
    In what function should I write Animator Blending code? Can I do it in UpdateVeloctiy() or is it better served elsewhere? For blending, it uses the current character velocity.

    Code (CSharp):
    1. CharacterAnimator.SetFloat("Velocity", velocity);
     
    Alvarezmd90 likes this.
  28. Alvarezmd90

    Alvarezmd90

    Joined:
    Jul 21, 2016
    Posts:
    151
    I'm wondering that too. I have tried this:
    Code (CSharp):
    1.         private void Update()
    2.         {
    3.             if (Player.HandleCharacterInputs && CanRun)
    4.                 Run = (Input.GetKey(KeyCode.LeftShift));
    5.             var RealSpdValue = Run ? 1 : .125f;
    6.             AnimSpeedMultiplier = Mathf.Lerp(AnimSpeedMultiplier, RealSpdValue, Time.deltaTime*8.0f);
    7.             if (_animator != null)
    8.             {
    9.                 if (CurrentCharacterState != CharacterState.Climbing && CurrentCharacterState != CharacterState.VineClimbing)
    10.                 {
    11.                     rightSpeed = Mathf.Lerp(rightSpeed, Vector3.Dot(
    12.                         Motor.BaseVelocity * AnimSpeedMultiplier, Motor.CharacterRight), Time.deltaTime*8.0f);
    13.                     zxSpeed = Mathf.Lerp(zxSpeed,Vector3.ProjectOnPlane(
    14.                        Motor.BaseVelocity * AnimSpeedMultiplier, Motor.CharacterRight).magnitude, Time.deltaTime*8.0f);
    15.                     var isForward = Vector3.Dot(Motor.BaseVelocity * AnimSpeedMultiplier, transform.forward) >= 0;
    16.                     var Multiplier = 1;
    17.                     if (!isForward)
    18.                     {
    19.                         Multiplier = Multiplier*-1;
    20.                     }
    21.                     _animator.SetFloat("Vertical", zxSpeed* Multiplier);
    22.                     _animator.SetFloat("Horizontal",rightSpeed);
    23.                     if (!Motor.GroundingStatus.IsStableOnGround)
    24.                     {
    25.                         if (CurrentCharacterState != CharacterState.Swimming)
    26.                             _animator.SetBool("OnGround", false);
    27.                         else
    28.                             _animator.SetBool("OnGround", true);
    29.  
    30.                         _animator.SetFloat("Jump", Motor.BaseVelocity.y);
    31.                     }
    32.                     else
    33.                     {
    34.                         _animator.SetBool("OnGround", true);
    35.                     }
    36.                 }
    37.             }
    38.         }
    I know it's horribly written and not efficient. xD

    Edited.
     
    Last edited: Feb 24, 2020
    mutp likes this.
  29. Yggdrazyl

    Yggdrazyl

    Joined:
    Jul 12, 2017
    Posts:
    16
    I don't understand what is the use of "Max Velocity for Ledge Snap".

    Even if I set it to a low value (let's say, 1), my character does not launch when going from an upwards slope to a downwards slope (like a big cube rotated 45 degrees).

    What I would like to get is, when my speed is above a certain value, then the character always launches from the upwards slope, and never snaps to the downwards slope. I feel the "Max Velocity for Ledge Snap" should be used here, but it does not seem to change anything.
    I have also fiddled with the Motor script, but coult not get the expected result.



    30 > 10, so i would like to get my character launching, no matter the angle.

    Any idea ? =x
     
    Last edited: Feb 24, 2020
  30. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    Is there a way to detect walls continuously and get hitcollider for walljumping or wall running? I tried character overlap and overlap collision, nothing worked.
     
    Last edited: Feb 28, 2020
  31. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    Rather than simply touching a wall, you need to know if a wall is directly in front of the player to properly detect wall slide conditions. So, you could fire a few short ray casts in the character's forward direction (spaced vertically, with their spacing less than the shortest wall in your game), just slightly farther than the capsule's radius, to get any walls exclusively in front of the player. If a hit normal is sufficiently horizontal for wall sliding, the player movement input is sufficiently forward-facing, and the input magnitude is high enough to initiate a wall slide, you can assume their input will push them against the wall and perform the slide. When the wall or input check fails, cancel the slide.
     
    andreiagmu likes this.
  32. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    A simple rule to remember when it comes to knowing when to update animator values: you should only update animator values when they change, and not more than once per frame ideally (updating an animator value twice in same frame is just redundant).

    KCC callbacks happen like this:
    • FixedUpdate
      • BeforeCharacterUpdate
      • UpdateVelocity
      • UpdateRotation
      • AfterCharacterUpdate
    So they all happen during the fixed update, and the other callbacks aren't listed here because they can be called anywhere between 0 and X times during a same fixed update

    Typically you should update your animator values that depend on velocity in AfterCharacterUpdate. You know you won't change your Velocity after that point in that frame, and that it will be up to date

    But if there are other animator values that can change outside of KCC callbacks, such as position/rotation which are interpolated, then you can update those in a regular Update(). Not in LateUpdate(), though because that happens after animation.

    If you don't want to have to worry about anything, then just update every single parameter in a regular Update, even character velocity. Sometimes it'll be redundant because you might update animator velocity twice in a row without the velocity value actually changing, but correcting that would be a micro-optimization that's probably not worth worrying about
     
    andreiagmu and mutp like this.
  33. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    You should do this with CharacterOverlap, but pay attention to the "inflate" parameter at the end. You should set "inflate" to a small value like 0.1f or 0.05f, so that you can detect colliders that are at a tiny distance from the character. By default, the KCC stays at a small distance (0.001f) from all collisions in order for its movement algorithm to work
     
  34. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    The issue here is that, since you'd be stable on either side of this cube, this doesn't count as a "ledge" for KCC. KCC considers that a ledge is when you'd be falling on the other side

    What we need in order to solve this is to make the ground detection distance as tiny as possible when you're over the speed limit. But it can't be 0, because you still want to detect ground properly when you're moving on flat ground at high speed. This is gonna sound like a contradiction with my last statement, but:
    try setting motor.GroundDetectionExtraDistance = -float.MaxValue; whenever you are over the velocity limit, and set it back to its regular value otherwise.

    Internally, KCC chooses a certain ground detection distance depending on certain settings like stepping, capsule radius, etc..., so the real ground detection distance varies depending on context, and the GroundDetectionExtraDistance is added to that at the end. However, the final distance is always clamped to be at least 'KinematicCharacterMotor.MinimumGroundProbingDistance' at the end of all calculations. So setting GroundDetectionExtraDistance to -float.MaxValue guarantees that the ground detection distance will be at the minimum value possible that works for detecting flat ground, but that lets you launch off slopes.

    I think I should give this scenario some more thought and see if I can make it more intuitive to implement this
     
  35. JacobDzwinel

    JacobDzwinel

    Joined:
    Dec 19, 2013
    Posts:
    26
    Hi,
    Can you point me how can I achieve smooth push effect on two or more KCC characters colliding? Something similar when rigidbody character with bigger mass collide with other rigidbody character. Currently they are just stop when collide with other KCC character.
     
  36. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    This is one of the downsides of kinematic characters; dynamics can be tricky

    However, you can fake it in OnMovementHit(). If you detect that the hit collider has a KinematicCharacterMotor component, you can add velocity to that motor.BaseVelocity in the direction of the hit normal. Like this:
    Code (CSharp):
    1. public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport)
    2. {
    3.     KinematicCharacterMotor hitMotor = hitCollider.GetComponent<KinematicCharacterMotor>();
    4.     if(hitMotor)
    5.     {
    6.         float pushForce = 100f;
    7.         hitMotor.BaseVelocity += pushForce * Time.deltaTime * -hitNormal;
    8.     }
    9. }
    But expect it to feel a bit flawed. The character that's pushing the other will "stop" its velocity way more than you'd expect. For true dynamic interactions, you would need a rigidbody-based character controller like the one in the Unity standard assets, which comes with its own important flaws compared to a kinematic one. Always a tough choice

    However, better dynamic interactions is something I'm investigating. There's a possibility that we can get the best of both worlds if I make modifications in the internal motor movement algorithm to behave like a mini physics engine in itself, but I don't have the solution yet
     
    Last edited: Mar 1, 2020
    andreiagmu and JacobDzwinel like this.
  37. FunnyDevJS

    FunnyDevJS

    Joined:
    May 3, 2016
    Posts:
    7
    Hello
    I am making a VR game using KCC.
    I just profiled my game.
    However, I found a lot of overhead in the Kinematic character controller.
    I am using Unity 2017.4.3 version.
    Is there a way to reduce Physics.overlapcapsulenonalloc calls?

    The picture below is where I took the settings.


     

    Attached Files:

    • kCC.jpg
      kCC.jpg
      File size:
      62.6 KB
      Views:
      430
    • kCC2.jpg
      kCC2.jpg
      File size:
      314.8 KB
      Views:
      446
  38. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    I see nothing suspicious with the settings, but those profiler timings are indeed not normal

    Can you try these 2 things:
    - in Edit > Project Settings > Physics, turn off "Auto Sync Transforms" (I cant remember if that setting existed in 2017.3 though)
    - if you profile the example scene of KCC with the default example character, do you see the same overhead?
     
    andreiagmu likes this.
  39. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,533
    Is there online api manual anywhre? MovePosition ...I noticed this was added in readme notes a while back.. would this be the thing to use if I wanted to add fly support to the controller.. ie toggle in out of controller/fly mode type thing
     
  40. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    An API reference archive is included with the package. To toggle flight, I just check if a bool on my character controller is true and handle UpdateVelocity differently in that case. Rigidbody.MovePosition just simulates object motion with physics (including friction) rather than direct teleportation. MoveWithPhysics is a PhysicsMover setting that controls whether or not this function is used.
     
  41. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,533
    I just noticed the noclip walkthrough pretty much had what I needed
     
  42. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,533
    I guess the exampleCharacter just never got all the little extra things that were put in the various walkthrough examples
     
  43. FunnyDevJS

    FunnyDevJS

    Joined:
    May 3, 2016
    Posts:
    7


    Thank you for your reply

    I tested with the "Auto Sync Transforms" option off.

    The odd thing is that the overhead increases when you turn on the option.

    It seems to come out up to 1.3ms.

    OverlapCapsuleNonAlloc overhead is down

    But SyncColliderTransform overhead is incread.

    I don't know what it is.
     

    Attached Files:

  44. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    how do i make player bounce straight up when jumping on a trampoline?

    mines doesnt bounce perfectly straight up with addvelocity() or add to base velocity.

    Code (CSharp):
    1. Motor.ForceUnground(0.1f);
    2.         Motor.BaseVelocity += (Motor.CharacterUp * 20) - Vector3.Project(Motor.BaseVelocity, Motor.CharacterUp);
     
  45. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    I'm not sure how BaseVelocity is to be used, since I override the UpdateVelocity function and modify the current velocity in that. But, I'm assuming by its name that BaseVelocity doesn't account for additional velocity from platforms and such. Check comments in the source if you need extra details on that.

    Either way, that code nullifies the player's up-aligned base velocity while keeping lateral base velocity. So, if you're moving laterally when you land on the trampoline, you will still have that extra lateral velocity. To nullify that as well, you could subtract Motor.BaseVelocity directly rather than projecting it onto the character's up vector first.
     
  46. Yggdrazyl

    Yggdrazyl

    Joined:
    Jul 12, 2017
    Posts:
    16
    Thanks for your reply ! Definitely going to check it later.

    Edit : Fixed the first issue by changing some Motor.CharacterUp to transform.up.

    I think I have found a bug / inconstistency with FramePerfectRotation, but I haven't been able to find the cause.
    When using FPR on a non-flat (spherical) surface, the character's model shakes (mostly because of some physical / graphical update inconstitency). The shaking is subtle, but definitely there.

    How to reproduce :
    1/ add the code from FPR into the playground scene's character
    2/ add a long and thin object to the character's model (like a very long nose), to make the bug easier to notice
    3/ go to the planet
    4/ notice the nose is slightly shaking



    In your example script, in UpdateVelocity, you wrote :
    Code (CSharp):
    1. if (Motor.GroundingStatus.SnappingPrevented && currentVelocityMagnitude > 0f)
    2. {
    3. // Take the normal from where we're coming from
    4. Vector3 groundPointToCharacter = Motor.TransientPosition - Motor.GroundingStatus.GroundPoint;
    5.  if (Vector3.Dot(currentVelocity, groundPointToCharacter) >= 0f)
    6.     effectiveGroundNormal = Motor.GroundingStatus.OuterGroundNormal;
    7.  else
    8.     effectiveGroundNormal = Motor.GroundingStatus.InnerGroundNormal;
    9. }
    1/ Why is that step necessary ?
    2/ Why is it necessary to know if we use inner or outer normal ? Can I remove it ?
     
    Last edited: Apr 2, 2020
  47. tvdmag

    tvdmag

    Joined:
    May 4, 2014
    Posts:
    2
    Sorry i know this is a very rudimentary question, but i hoped someone might be able to point me in the right direction.
    How would you properly implement variable jump heights from key press duration with this controller?, at best I'm updating the next jump.
     
  48. Gooren

    Gooren

    Joined:
    Nov 20, 2015
    Posts:
    332
    I have implemented physic player interactions with various smaller non-kinematic rigidbodies located in the levels. Similar to Penumbra, Amnesia or SOMA.

    Everything works nice unless I start running while "holding" a rigidbody. Held rigidbody stutters mid-air due to player KCC positional update not being in sync with the interactions positional update that works by directly changing held rigidbody velocity in FixedUpdate.

    Is there a way to make them perfectly synchronized even when player is running?

    Thanks!
     
  49. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    i tried modifying base velocity. It works a bitt better. Only issue is if you press and hold jump, you bounce up 2x higher.
     
  50. Alvarezmd90

    Alvarezmd90

    Joined:
    Jul 21, 2016
    Posts:
    151
    This asset is the greatest. I'm still using it for my project and discovering new features I overlooked. :)
    It's very well structured and comfortable to work with.

    Thanks PhilSA for creating this.
     
    Gooren likes this.