Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

[Released] Kinematic Character Controller

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

  1. Olog555

    Olog555

    Joined:
    Aug 20, 2017
    Posts:
    3
    Greetings from Russia, comrade. I have had experience using this asset in an authoritative server. Also faced this problem.
    1) Errors in prediction. I use inputs and send them to the server, but I get strong discrepancies (digging in the code, I still don't understand what caused them).
    2) The problem of re-simulation. I tried to insert the server position and reapply all the pressed inputs but still ran into the problem.
    ----
    I can assume that there is some kind of bandwidth and this greatly affects this. I cannot use the keys alone in a loop, there is a delay.
    Communicating with people who have used this asset - they shrug their shoulders because they did not deal with multiplayer. Having written a letter to the author already two weeks ago (3 times), I have not received an answer. I decided to give up the idea with this asset and write my own controller (based on unity character controller)
     
    KyleChallis and julio_kolbapps like this.
  2. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Here's my script for Unity's CC, if I get it working with KCC, I'll post an update:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class LedgeSlidePlayer : MonoBehaviour
    6. {
    7.     Vector3 LeftRay;
    8.     Vector3 LeftEdgeNormal;
    9.     Vector3 RightRay;
    10.     Vector3 RightEdgeNormal;
    11.     Vector3 ForwardRay;
    12.     Vector3 EdgeNormal;
    13.     bool OnEdge;
    14.     float EdgeGapHeight = Mathf.Infinity;
    15.     public LayerMask NoPlayerNoEnemy;
    16.     Vector3 Ground;
    17.     bool Stop;
    18.     Vector3 MoveVector;
    19.     float Gravity = -8f;
    20.     float Speed = 2f;
    21.     Vector3 ProjectedVector;
    22.     CharacterController cc;
    23.    
    24.     // Start is called before the first frame update
    25.     void Start()
    26.     {
    27.         NoPlayerNoEnemy = ~0; // set everything
    28.         NoPlayerNoEnemy = ~(1 << LayerMask.NameToLayer ("Player") | 1 << LayerMask.NameToLayer ("Enemies")); // remove player and enemies
    29.         cc = GetComponent<CharacterController>();
    30.     }
    31.  
    32.     // Update is called once per frame
    33.     void FixedUpdate()
    34.     {
    35.         MoveManual();
    36.        
    37.         // LeftRay
    38.         Color ColorLeftRay;
    39.         Vector3 LeftRayOffset =(Quaternion.Euler(0f, 20f, 0f) * transform.forward) * 0.4f;
    40.         LeftRay = transform.position + LeftRayOffset;
    41.        
    42.         if (Physics.Raycast(LeftRay, Vector3.down, EdgeGapHeight, NoPlayerNoEnemy))
    43.         {
    44.             ColorLeftRay = new Color(0,255,0,255); // green
    45.         }
    46.         else
    47.         {
    48.             Vector3 origin = new Vector3(LeftRay.x, Ground.y + -0.02f, LeftRay.z);
    49.             Vector3 direction = new Vector3(-LeftRayOffset.x, 0, -LeftRayOffset.z);
    50.             RaycastHit hit;
    51.            
    52.             ColorLeftRay = new Color(255,0,0,255); // red
    53.            
    54.             if (Physics.Raycast(origin, direction, out hit, EdgeGapHeight, NoPlayerNoEnemy))
    55.             {
    56.                
    57.                 Debug.DrawRay(origin, direction, new Color(255, 16, 242, 255));
    58.                 LeftEdgeNormal = hit.normal;
    59.             }
    60.         }
    61.        
    62.         Debug.DrawRay(LeftRay, new Vector3(0, -1, 0) * 10f, ColorLeftRay);
    63.        
    64.         // RightRay
    65.         Color ColorRightRay;
    66.         Vector3 RightRayOffset = (Quaternion.Euler(0f, -20f, 0f) * transform.forward) * 0.4f;
    67.         RightRay = transform.position + RightRayOffset;
    68.        
    69.         if (Physics.Raycast(RightRay, Vector3.down, EdgeGapHeight, NoPlayerNoEnemy))
    70.         {
    71.             ColorRightRay = new Color(0,255,0,255); // green
    72.         }
    73.         else
    74.         {
    75.             Vector3 origin = new Vector3(RightRay.x, Ground.y + -0.02f, RightRay.z);
    76.             Vector3 direction = new Vector3(-RightRayOffset.x, 0, -RightRayOffset.z);
    77.             RaycastHit hit;
    78.            
    79.             ColorRightRay = new Color(255,0,0,255); // red
    80.            
    81.             if (Physics.Raycast(origin, direction, out hit, EdgeGapHeight, NoPlayerNoEnemy))
    82.             {
    83.                 Debug.DrawRay(origin, direction, new Color(255, 16, 242, 255));
    84.                 RightEdgeNormal = hit.normal;
    85.             }
    86.         }
    87.        
    88.         Debug.DrawRay(RightRay, new Vector3(0, -1, 0) * 10f, ColorRightRay);
    89.        
    90.         //ForwardRay
    91.         Color ColorForwardRay;
    92.         ForwardRay = transform.position + (transform.forward * 0.4f);
    93.        
    94.        
    95.         if (Physics.Raycast(ForwardRay, Vector3.down, EdgeGapHeight, NoPlayerNoEnemy))
    96.         {
    97.             ColorForwardRay = new Color(0,255,0,255); // green
    98.             EdgeNormal = Vector3.zero;
    99.         }
    100.         else
    101.         {
    102.            
    103.             ColorForwardRay = new Color(255,0,0,255); // red
    104.            
    105.             RaycastHit hit;
    106.             if (Physics.Raycast(transform.position, Vector3.down, out hit, EdgeGapHeight, NoPlayerNoEnemy))
    107.             {
    108.                 Debug.DrawRay(transform.position, new Vector3(0,-1,0) * 10f, new Color(0, 0, 255, 255));
    109.                
    110.                 Ground = hit.point;
    111.                
    112.                 Vector3 origin = new Vector3(ForwardRay.x, Ground.y + -0.02f, ForwardRay.z);
    113.                 Vector3 direction = new Vector3(-transform.forward.x, 0, -transform.forward.z);
    114.                 if (Physics.Raycast(origin, direction, out hit, EdgeGapHeight, NoPlayerNoEnemy))
    115.                 {
    116.                     EdgeNormal = hit.normal;
    117.                 }
    118.             }
    119.            
    120.         }
    121.         Debug.DrawRay(ForwardRay, new Vector3(0, -1, 0) * 10f, ColorForwardRay);
    122.        
    123.         // bool tests
    124.         if (LeftEdgeNormal == EdgeNormal && RightEdgeNormal != EdgeNormal)
    125.         {
    126.             Stop = true;
    127.         }
    128.         else
    129.         {
    130.             Stop = false;  
    131.         }
    132.        
    133.         if (RightEdgeNormal == EdgeNormal && LeftEdgeNormal != EdgeNormal)
    134.         {
    135.             Stop = true;
    136.         }
    137.         else
    138.         {
    139.             Stop = false;  
    140.         }
    141.        
    142.        
    143.         //move
    144.         MoveVector = Quaternion.Euler(transform.eulerAngles) * new Vector3(0f, Gravity, CurrentSpeed);
    145.         ProjectedVector = Vector3.ProjectOnPlane(MoveVector, EdgeNormal);
    146.        
    147.         if (Stop)
    148.         {
    149.             ProjectedVector = Vector3.zero;
    150.         }
    151.         else
    152.         {
    153.             if (transform.InverseTransformDirection(MoveVector).z > 0f)
    154.             {
    155.                 cc.Move(ProjectedVector * Time.deltaTime);
    156.             }
    157.             else
    158.             {
    159.                 cc.Move(MoveVector * Time.deltaTime);
    160.             }
    161.         }
    162.     }
    163.    
    164.     float CurrentSpeed;
    165.     float CurrentStrafe;
    166.     float MaxSpeed = 8f;
    167.     float Acceleration = 0.8f;
    168.     float Deceleration = 12f;
    169.    
    170.     void MoveManual()
    171.     {
    172.         //ForwardsBackwards
    173.         if (Input.GetButton("Up") && CurrentSpeed < MaxSpeed)
    174.         {
    175.             CurrentSpeed += Acceleration;
    176.         }
    177.         else if (Input.GetButton("Down") && CurrentSpeed > -MaxSpeed)
    178.         {
    179.             CurrentSpeed -= Acceleration;
    180.         }
    181.        
    182.         if (Mathf.Abs(CurrentSpeed) > 0.05f)
    183.         {
    184.             CurrentSpeed -= Deceleration * Mathf.Clamp(Time.deltaTime, 0, 1) * CurrentSpeed;
    185.         }
    186.         else
    187.         {
    188.             CurrentSpeed = 0f;
    189.         }
    190.        
    191.         //TankTurn
    192.         if (Input.GetButton("Right"))
    193.             {
    194.             transform.eulerAngles += new Vector3(0, 4, 0);
    195.             }
    196.         else if (Input.GetButton("Left"))
    197.         {
    198.             transform.eulerAngles += new Vector3(0, -4, 0);
    199.         }
    200.        
    201.  
    202.        
    203.     }
    204. }
    205.  
     
  3. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    19
    Can anyone tell me how to get a reference to an Animator please, so I can swap between clips depending on velocity?
    I've been bashing my head against a wall trying to understand the the 'documentation'. I tried adding an animator component to ExampleCharacterController.cs's Awake() function, but it always returns null.
     
  4. Kin0min

    Kin0min

    Joined:
    May 12, 2015
    Posts:
    8
    Code (CSharp):
    1. public class *your script* : MonoBehaviour
    2. {
    3. // we can define it as public and drag/drop the object with the Animator component
    4. public Animator anim;
    5.  
    6. void Start()
    7.     {
    8.        //if this script component is attached to the same object with the Animator component we can have it add itself too
    9.        if ( anim == null)
    10.        {
    11.        //anim = GetComponent<Animator>();
    12.        }
    13.     }
    14. }
    15.  
     
  5. JauntyBear

    JauntyBear

    Joined:
    Mar 26, 2018
    Posts:
    43
    is there any update on this? I've tried the prior solution but the code provided in ExamplePlayer is different now
     
  6. JauntyBear

    JauntyBear

    Joined:
    Mar 26, 2018
    Posts:
    43
    Eventually I've set the input character controller as below to be more console friendly
    Code (CSharp):
    1. _moveInputVector = cameraPlanarRotation * new Vector3(0f, 0f, Mathf.Clamp(inputs.MoveAxisForward * axisForwardMultiplier,0f,1f));
    2.                                 _lookInputVector = Quaternion.Euler(0f, moveInputVector.x * rotationSpeed, 0f) * Motor.CharacterForward;
     
  7. kantagara

    kantagara

    Joined:
    Sep 15, 2014
    Posts:
    11
    Is there an easy way to prevent MotorCharacterController to react to every uneven surface so drastically? I have a lot of uneven surfaces/terrain stuff and I really get bothered by the fact that it reacts so drastically to it.
     
    KyleChallis likes this.
  8. Gooren

    Gooren

    Joined:
    Nov 20, 2015
    Posts:
    278
    The easiest and safest way of doing so would be changing camera follow speed parameter. Not sure how its called now. Just some camera positional follow easing should do.
     
  9. kantagara

    kantagara

    Joined:
    Sep 15, 2014
    Posts:
    11
    Oh forgot to say that I'm making an FPS, do you think easing could help there as well? Because character hands would move up and that would look weird on the camera itself.
     
  10. Gooren

    Gooren

    Joined:
    Nov 20, 2015
    Posts:
    278
    You could lock the hands to the camera. Then, make sure eased position delta is never greater than character capsule radius or lock max character velocity, so that the hands and the camera don't clip into things etc.
     
  11. nobluff67

    nobluff67

    Joined:
    Nov 3, 2016
    Posts:
    259
    I have seen puppetmaster mention once in this thread about 3 years ago, has anyone used the two products together successfully?

    I am currently trying to get them to work together but am struggling.
     
  12. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    21
    Hi guys,

    first of all: many thanks for this great work!! Your asset is amazing and very helpful. I’m new with unity. I’m coming from app development world (Flutter, Swift) and all this stuff with 3D physics and mathematics is very……. new … I will need some time to understand better.

    For my game I have a lion as character. First of all I try to handle a movement like that (I saw this on your youtube channel):



    1) The character should not look always forward when I move the camera with Mouse Y and Y Axis. So I need to see also the face from my lion :)

    -EDIT- Nr. 1 was solved by comment out the following line:
    // _lookInputVector = cameraPlanarDirection;


    2) The character should rotate to the direction he moves. With your Walkthrough examples the character always is looking forward.

    3) This would be optional but amazing: the character should always rotate parallel to the ground, for example when he goes up to a mountain. With my tries this works only with hard camera flickering.

    I've recorded a video to show you what I have and what's my intention:



    Maybe there is a Walktrough with this movement behavior from which I could learn?

    Thanks in advance for your assistance. I really appreciate it!

    Best regards,
    Asored
     
    Last edited: May 3, 2021
  13. JimRoot

    JimRoot

    Joined:
    Sep 11, 2013
    Posts:
    77
    Hey! Is there a way to get the character pushed around by another character? I cant get this working somehow. Like for example that the player character gets pushed by the ai players in the playground demo scene.
    Thanks
     
  14. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    21
    I've get it to work by following the main example in your package. There I found logic for "Orientation method" -> "Towards Movement" and "Bonus Orientation Method" -> "Towards Ground Slope and Gravity".

    But: The camera is terrible lagging and will be unable to game with the character...can I only rotate the character on slope without rotating the camera too? Because every small slope on terrain will adjust the camera...

    Here is a video to show you how it looks:



    The code part:


    if (Motor.GroundingStatus.IsStableOnGround)
    {
    Vector3 initialCharacterBottomHemiCenter = Motor.TransientPosition + (currentUp * Motor.Capsule.radius);

    Vector3 smoothedGroundNormal = Vector3.Slerp(Motor.CharacterUp, Motor.GroundingStatus.GroundNormal, 1 - Mathf.Exp(-BonusOrientationSharpness * deltaTime));
    currentRotation = Quaternion.FromToRotation(currentUp, smoothedGroundNormal) * currentRotation;

    // Move the position to create a rotation around the bottom hemi center instead of around the pivot
    Motor.SetTransientPosition(initialCharacterBottomHemiCenter + (currentRotation * Vector3.down * Motor.Capsule.radius));
    }
    else
    {
    Vector3 smoothedGravityDir = Vector3.Slerp(currentUp, -Gravity.normalized, 1 - Mathf.Exp(-BonusOrientationSharpness * deltaTime));
    currentRotation = Quaternion.FromToRotation(currentUp, smoothedGravityDir) * currentRotation;
    }


    Is there a workaround to fix this?
     
    KyleChallis likes this.
  15. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    559
    While trying to implement a wall-running feature, I've been trying to track down an issue where my character was sticking to walls (velocity suddenly dropping to zero, and not falling), even when the wall was a very simple box collider.

    Eventually spotted the Physics.ComputePenetration() call in InternalCharacterMove() returning a resolutionDistance of zero and a huge/bad normal while the player was stuck. Adding an if (resolutionDistance!=0.0f) to ignore the questionable hit seems to have resolved it.

    Not sure if it's caused any unexpected side-effects... seems OK so far... (I'm using Unity 2020.2.2f1)6
     
    Gooren likes this.
  16. Gooren

    Gooren

    Joined:
    Nov 20, 2015
    Posts:
    278
    It would be nice if you could point this out to the asset author by e-mail. He always reacts to mails, but hardly ever shows here in this thread.
     
  17. Zhialus

    Zhialus

    Joined:
    Jan 3, 2019
    Posts:
    16
    This is probably a hacky fix, but without delving too far into the camera controller's code to find a better way to implement it it's the best I've got. Place a new script on the "CameraTarget" nested under your character gameobject with the code:


    void LateUpdate()
    {
    if(transform.rotation != Quaternion.identity)
    {
    transform.rotation = Quaternion.identity;
    }
    }


    From what I can tell, the camera rotates with the character so that it works with planetoid-style orientation. At a moments glance, the reason the camera is jittering is because the 'CameraTarget' object is rotating as it's a child of the character gameobject. Basically what this script does is every frame it will reset the child gameobjects rotation to align with the WORLD AXIS instead of its local PARENT AXIS aka no rotation at all

    I would try to find something cleaner for a permanent solution, but if you need something quick and dirty for testing purposes this works. Maybe also look into using cinemachine instead of the camera controller included in KCC if you haven't already. CameraTest.gif
     
    asored likes this.
  18. asored

    asored

    Joined:
    Nov 6, 2020
    Posts:
    21
  19. brummer

    brummer

    Joined:
    Jul 3, 2013
    Posts:
    20
    @PhilSA or anyone else; do you have any idea why my two KCC characters don't really collide with each other? They just clip through. I have rigidbody interaction set to dynamic and the layers they are on should be colliding.
     
  20. brummer

    brummer

    Joined:
    Jul 3, 2013
    Posts:
    20
    Issue seems fixed now. No idea what caused it, as i double-checked every setting.
    Removing all components off of the characters and adding them back the same way seemed to fix the issue.
     
  21. brummer

    brummer

    Joined:
    Jul 3, 2013
    Posts:
    20
    Does anyone have any idea why KCC updates in fixedupdate, but calls for deltatime rather than fixeddeltatime?
     

    Attached Files:

  22. Onigiri

    Onigiri

    Joined:
    Aug 10, 2014
    Posts:
    222
    Isn't deltatime returns fixed delta time if you call it from fixed update?
     
  23. Gooren

    Gooren

    Joined:
    Nov 20, 2015
    Posts:
    278
  24. Censureret

    Censureret

    Joined:
    Jan 3, 2017
    Posts:
    359
    Hey guys i just bought the the asset and i am trying to get it to work with the navmesh and some animation motion. Does anyone have a script i can look at as an example? :)
     
    dadahsueh likes this.
  25. FcsVorfeed

    FcsVorfeed

    Joined:
    Aug 15, 2014
    Posts:
    38
    hi, when I upgrade new version,this is not working!
     
  26. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    15
    Hey I was wondering how would one go about adapting the new input system to work with the KCC?
     
  27. thangnh111

    thangnh111

    Joined:
    Aug 4, 2020
    Posts:
    9
    Hi guys, i have problem when use kcc with networking. At resimulate step, i set input and it will jump multiple time, how to cancel the previous jump?
     
  28. thangnh111

    thangnh111

    Joined:
    Aug 4, 2020
    Posts:
    9
    Does it still support networking, i can't find network example in the package content upload_2021-6-23_17-34-43.png
     
  29. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    27,824
    It doesn't support any specific networking packages but it does have some implementation details so you can implement it yourself. It's not the best package if you don't want to code anything :)
     
  30. thangnh111

    thangnh111

    Joined:
    Aug 4, 2020
    Posts:
    9
    @hippocoder i have try to itergrate kcc with my networking game. Method SetInput() work very well for ground movement except Jumping, when i re-simulate, my player will jump multiple time at client. I thinking about passing previous KCCState to solve it like Phil suggest at Walkthrough document. but KCC state is too big for my expected bandwidth even it have compressed
     
  31. thangnh111

    thangnh111

    Joined:
    Aug 4, 2020
    Posts:
    9
    I will very appreciate if there is an example or document about what is the correct way to intergrate kcc with networking
     
    dadahsueh likes this.
  32. thangnh111

    thangnh111

    Joined:
    Aug 4, 2020
    Posts:
    9
    Hi guys, i need a method similar with OnMovementHit but working even player not move, can i do that ?
     
  33. dadahsueh

    dadahsueh

    Joined:
    Mar 5, 2019
    Posts:
    1
    New
    OnDiscreteCollisionDetected(Collider hitCollider)
    This is called when the character detects discrete collisions (collisions that don't result from the motor's capsuleCasts when moving)
     
  34. digimbyte

    digimbyte

    Joined:
    Jun 23, 2012
    Posts:
    42
    is there any way I can update objects positions without stuttering?
    https://cdn.discordapp.com/attachments/854886116070916117/860305627096154134/Physics_stutter.mp4

    I'm using a Floating Origin system for my world and updating the object, I am checking its distance and enabling and disabling the PhysicsMover Script. When it's enabled it has a chance of stuttering
    **MAIN PROBLEM ON LINE 14**
    Code (CSharp):
    1.  
    2.         Vector3 RelativePosition = Entity.RealPosition + GridOffset;
    3.         float Distance = Vector3.Distance(Vector3Int.zero, RelativePosition);
    4.         if (Entity.Physics != null)
    5.         {
    6.             if (Distance > GridRadius)
    7.             {
    8.                 if (Entity.Physics.enabled == true) {
    9.                     Entity.Physics.enabled = false;
    10.                     Entity.Physics.transform.position = Vector3.zero;
    11.                     Entity.transform.position = (RelativePosition.normalized * (Distance + Mathf.Max((Distance - GridRadius), 0)));
    12.                 }
    13.                 else
    14.                 Entity.transform.position = (RelativePosition.normalized * (Distance + Mathf.Max((Distance - GridRadius), 0)));
    15.             }
    16.             else
    17.             {
    18.                 if (Entity.Physics.enabled == false)
    19.                 {
    20.                     Entity.Physics.enabled = true;
    21.                     Entity.Physics.SetPosition(RelativePosition);
    22.                     Entity.transform.position = Vector3.zero;
    23.                 }
    24.                 else
    25.                 Entity.Physics.SetPosition(RelativePosition);
    26.             }
    27.         }
     
  35. thangnh111

    thangnh111

    Joined:
    Aug 4, 2020
    Posts:
    9
    Hi guys, i have got a problem with kcc, the gravity always pull player with Motor.CharacterDown direction (from head to feet direction), so when player lying on ground, gravity will pull him horizontally.

    My question is: How to make gravity alway pull player vertically?

    upload_2021-7-5_11-30-26.png
     
  36. Madrize

    Madrize

    Joined:
    May 23, 2016
    Posts:
    3
    Whats the best way to add the ability to float ? Any tips welcome
     
  37. jamesdibnah

    jamesdibnah

    Joined:
    Jun 4, 2018
    Posts:
    2
    Hey everyone,

    I am currently having issues with the character pushing heavy rigid bodies, currently the character is able to push the object as if it weighs nothing.

    My attempts already:

    I have attempted to affect the players walking speed when colliding into Rigidbody props, the higher the mass the slower they are however I feel that this is a pretty hacky way and very annoying to detect when the player is no longer colliding with said prop. OnCollisionExit would instantly trigger after OnCollisionEnter, which means I am unable to use the exit event.

    Does anyone know if this pack has any feature specifically built for interaction between characters pushing a heavy mass Rigidbody or know any better work arounds.

    Thanks
     
  38. tconkling

    tconkling

    Joined:
    Jul 13, 2012
    Posts:
    13
    I believe KCC is only designed to be used with a vertical capsule collider - that is, your character's capsule should not have any rotation in the X or Z axes. If your character is lying down, that's either a purely visual state change (meaning it's just handled by animation), or it's a visual state change with a capsule _dimension_ change, but not an orientation change.
     
  39. RedChainsaw

    RedChainsaw

    Joined:
    Jan 19, 2015
    Posts:
    2
    On the Kinematic Character Motor component change the Rigidbody Interaction Type to: Simulated Dynamic.
     
  40. BlackBunnyCrankn

    BlackBunnyCrankn

    Joined:
    Mar 21, 2020
    Posts:
    8
    Noob question: When i create a AI\NPC and attach a navmesh agent and add a ragdoll system to the NPC my character seems to jitter\get pushed when close to the NPC. Due to all the kinematic colliders on the NPC.

    Should i be using the character motor\Kinematic controller to manage the movement and collisions for AI if i have one for my player? Or is this just a case of my needing to add something in the code to stop enemies from pushing and jitterings the player.

    Really having issues creating AI using navmesh agent that interract with a player which has a kinematic controller. If anybody can help it would be amazing.
     
    Last edited: Jul 25, 2021
  41. bigd

    bigd

    Joined:
    Feb 14, 2014
    Posts:
    40
    Hi, I have a couple questions and am hoping for a little guidance. Firstly, KCC has been amazing at creating a smooth, predictable movement, thanks for creating this awesome asset.

    My particular game is a networked sci-fi game where players control spaceships. Without getting to heavy into the networking details, players move their local copy of their spaceship (that has KCC enabled on it) and the server replicates this movement to other players on the server. I disable KCC on the server-side because it takes the client's position as the truth for where their spaceship's position is at.

    I'm having difficulty wrapping my head around how to handle players colliding with other spaceships. Ideally they will "react" to bumping into the other player ships by bouncing off them, causing damage, etc. Right now when they collide, they don't actually interact at all.

    Any hints on how this would be managed? Would I need to code these collisions manually? How would I detect such a collision occured?

    Thanks in advance!
     
    Last edited: Jul 27, 2021
  42. SoumyaRipan86

    SoumyaRipan86

    Joined:
    Aug 19, 2019
    Posts:
    9
    Hi Guys, I am facing this issue where the character is launching off from the track on hitting the edge of it. The more the hitting force the launch is more.

    I have added a gameplay video for reference.



    So in this scenario, I only apply a constant Z velocity of 10m/s and some X velocity while drifting sideways but "Zero" Y velocity is added from code. Yes, there is a gravity force acting downward (-ve Y axis) whenever the character GroundingStatus.IsStableOnGround is false.

    This behaviour is undesirable for the game mechanics and just looks unrealistic.haha

    Could anybody please help me with any solution for this or I am missing something in KCC ?
    @PhilSA
     
  43. thangnh111

    thangnh111

    Joined:
    Aug 4, 2020
    Posts:
    9
    Hi guys, does any one know the difference between GroundNormal, InnerGroundNormal, OuterGroundNormal of kcc groundstatus. I have visualize it by debug.drawline, and they are the same.
     
  44. Sixoul

    Sixoul

    Joined:
    Jan 9, 2014
    Posts:
    15
    Has anyone found a solid way to implement a fsm that doesn't use enums? I've seen state machines where states hold actions and it iterates through those actions but I don't think that would work with this KCC.
     
  45. jamesdibnah

    jamesdibnah

    Joined:
    Jun 4, 2018
    Posts:
    2
    Thanks man, I think I was really just over complicating things! I did try Simulated Dynamic before however it never allowed me to push it. It's not until me coming back to this project that I've noticed that the character can only push up to 2kg of weight whereas my objects are like 59kg.

    Thanks again!
     
  46. KingBlackToof

    KingBlackToof

    Joined:
    Nov 22, 2014
    Posts:
    2
    Here's a, hopefully, simple question.

    Moving an object with the usual PhysicsMover but NOT Oscillating it.
    I want it to move to a set place and that's it, maybe move back upon script command.

    It's only a simple platform, so I feel the Director, Animator, Animations is overkill.

    Or do I use Motor.Move()?
     
  47. Chrispins

    Chrispins

    Joined:
    Dec 9, 2014
    Posts:
    11
    Hey all,

    I'm currently considering getting this controller system from the asset store, but I wanted to ask a few questions to see if it would be well-suited to the game project I'm planning to start. Hopefully someone here is experienced enough to give some feedback.

    Firstly, I'll explain the most relevant planned features for the game. It is to be networked using MLAPI for a moderate amount of simultaneous players (in the range of hopefully 32 or more), and it'll center around constructing large modular vehicles (airships, large walking contraptions, boats, ect.) where crew members will be able to freely walk, jump, and climb about on them without the risk of falling off. The vehicles will of course be frequently moving around a large landscape, while at the same time being modifiable and scalable (consisting of large blocks that can be added or destroyed).

    1. Considering that this character controller requires a PhysicsMover component to be added to any moving objects that are to be 'rideable', how well would this scale without affecting performance too much? Could I have, say hundreds of cube-shaped PhysicsMover objects, all attached to other adjacent PhysicsMover cubes, with the character being able to transition seamlessly between them as he walks?
    2. Is it feasible to add functionality for the character to rotate along with the PhysicsMover objects, in addition to the already-implemented translation matching as shown in the demonstration videos/project?
    3. Lastly, how about the feasibility of having the player continue to match the velocity of PhysicsMover objects even after having jumped and left the surface? This would be to prevent players from accidentally 'flinging' off fast-moving objects after jumping, or otherwise making platforming difficult while on the large moving contraptions. I imagine this could perhaps be done with either a trigger zone around PhysicsMover objects that forces the character to continue to match the X and Y components of motion, or perhaps downward raycasts that detect if a PhysicsMover is underneath the character?
    I appreciate any feedback you guys might have!

    Thanks
     
  48. Hannibal_Leo

    Hannibal_Leo

    Joined:
    Nov 5, 2012
    Posts:
    350
    @PhilSA

    I think I found a bug.
    After writing my own character with proper state machine and abilities (Walk, Jump, ..) I was able to run up at impossible angles.

    2.5h of debugging led me to the 2571th line of the class "KinematicCharacterMotor.cs" he didn't find the ground he was colliding with, so he couldn't adjust the movement input to not slide up the steep angle.

    changing
    Code (CSharp):
    1. distance + GroundProbingBackstepDistance
    to
    Code (CSharp):
    1. distance + GroundProbingBackstepDistance * 2
    solved the problem.

    full cast:
    Code (CSharp):
    1. // Capsule cast
    2.             int nbUnfilteredHits = Physics.CapsuleCastNonAlloc(
    3.                 position + (rotation * _characterTransformToCapsuleBottomHemi) - (direction * GroundProbingBackstepDistance),
    4.                 position + (rotation * _characterTransformToCapsuleTopHemi) - (direction * GroundProbingBackstepDistance),
    5.                 Capsule.radius,
    6.                 direction,
    7.                 _internalCharacterHits,
    8.                 distance + GroundProbingBackstepDistance * 2,
    9.                 CollidableLayers & StableGroundLayers,
    10.                 QueryTriggerInteraction.Ignore);
    This code is located at the
    CharacterGroundSweep()
    Method.

    Now he is able to detect the ground and adjust movement according to the steep angle, preventing sliding along it into the sky. xD

    Also you should consider splitting the character motor up into some subclasses 2655 lines of code in one file is about 10 times too much. But as this code isn't ment to be altered, it's up to you.

    But what would be almost required is a proper state machine on top of the controller. In your examples the states are defined by one Enum and the switch statement is in every single method call. The switch itself is redumdant code and also the Character one might end up with would have ~1000 lines of code or more. That's bad to maintain. And everyone has to come up with their own solution, but everyone needs a solution to this problem.

    Took me 2 days to come up with something ..

    My solution:

    States as Monobehaviours (could be ScriptableObjects)
    upload_2021-8-25_13-5-58.png

    Abilities as MonoBehaviours (could be ScriptableObjects)
    upload_2021-8-25_13-6-31.png

    And the "Example Character" (renamed to FPS Controller) as Statemachine (deciding which state gets updated)
    upload_2021-8-25_13-7-59.png

    Hierarchy:
    upload_2021-8-25_13-8-57.png

    The FPS Controller gets all the calls,
    SetInputs()
    ,
    BeforeCharacterUpdate()
    , .. and passes them to the current state without executing any code inside them, except for chaning states.
    A state is just a collection of Abilities and passes all calls to them. (it can overwrite calls when needed)
    And Abilities actually have the code that drives the character.

    KinematicCharacterMotor -> Controller -> (current) State -> (List of) Abilities

    But overall the controller is really cool, it moves super smooth and all the possibilities with excluding colliders is 100% what I wanted.
     
    Last edited: Aug 25, 2021
    Vincent13122 likes this.
  49. robingerster

    robingerster

    Joined:
    May 21, 2020
    Posts:
    2
    @PhilSA
    Hey I have two questions if you dont mind.

    1. How can you get the relative forwards and sideways velocity of the player? Motor.velocity returns the velocity with respect to the world. I would want this relative to where play player is moving.

    2. I read that when simulating manually (for networking) you pass Photon.Bold.deltaTime does something similair exist if I use just photon?.
     
    Last edited: Aug 28, 2021
  50. Marsunpaisti

    Marsunpaisti

    Joined:
    May 3, 2018
    Posts:
    7
    I'm looking to integrate with Photon Fusion. I see you are already ahead of other controllers with the possibility to call the update method manually with a deltatime.
    Is there an internal state on the motor / controller, and is it exposed? Or are they purely functional? I'm wondering because I'd like to synchronize the internal state if there is one, so I need access the internal code to be able to slap [Networked] attributes on the variables which also happens to require empty getter&setter fields for them to work with Fusion's code generation.
     
unityunity