Search Unity

[Released] Kinematic Character Controller

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

  1. TehReason

    TehReason

    Joined:
    May 14, 2013
    Posts:
    53
    yeah i can imagine combining both kind of behaviors in one solution is nearly impossible.

    Thank you very much sir!
     
  2. rad1c

    rad1c

    Joined:
    Feb 26, 2016
    Posts:
    21
    That's a live project so it is not possible I'm afraid. I can privately share with you my KCC-related scripts though. Might be I made a mistake somewhere.
     
  3. Guerrilla705

    Guerrilla705

    Joined:
    Jan 23, 2014
    Posts:
    6
    Hi! This may be a silly question, but I'm curious why the deltaTime that seems to be passed through to things like the UpdateVelocity callback is Time.deltaTime, while those calls are made from within the FixedUpdate segment? Since the UpdateVelocity (etc.) callbacks are being called with the fixedDeltaTime separation, shouldn't we be using that for our dt in calculations rather than the time from the last frame like in Update? Like I said, I'm probably just missing something obvious, but I couldn't seem to figure it out from reading this thread or from looking through the code.

    Thanks, and great work!
     
  4. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    Time.deltaTime, when queried at the moment where the engine is going through its fixedUpdate, actually has the value of Time.fixedDeltaTime.

    I also know there is one small difference that made it a better choice than fixedDeltaTime, but to be perfectly honest..... I forgot what it was! It had something to do with Time.timescale, I think
     
  5. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    I understand. Here's a simpler suggestion, though: you could import your problematic scene in the default KCC project, and see if it's still happening. It would help root out the cause of the problem

    Edit: just saw your PM. I'll take a look at that
     
    Last edited: Jan 19, 2018
  6. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    My guess is that this happens because you deactivated the character mid-update. Can you try doing this in AfterCharacterUpdate(), or BeforeCharacterUpdate()?
     
  7. owlyoop

    owlyoop

    Joined:
    Jun 12, 2017
    Posts:
    2
    I finally bought this after giving up on my own character controller. This is super great and indepth! I've been reading through it all today, so I might just need more time for what I'm trying to do. My own char controller had quake's air strafing and air control. I've been struggling to implement that to this controller, using the example prefab as my start, and I'm sort of lost now. If anyone else has successfully done that then it'd be nice to see how they did.

    Edit: I sort of got it working, doesn't feel quite right. How would I detect if the player is only holding left or right?
     
    Last edited: Jan 21, 2018
  8. nitoh

    nitoh

    Joined:
    Mar 20, 2014
    Posts:
    17
    Hi everyone!

    I bought the asset, but because of my limited scripting abilites i have a problem.
    I use your root motion example character controller, and modified it, i just want to rotate my AnimatorObject (the object that has the animator component) to a specific target every frame. Like a lock on target function. The locking works, but my character stuttering when moving. my my transform rotation code is in void update in MyCharacterController, and its oviously not good.

    Where should I place this tiny few lines of code?

    Thank your answers in advance!

    Edit: Maybe I got it working. placed my code under BeforeCharacterUpdate function.
     
    Last edited: Jan 21, 2018
  9. Guacamolay

    Guacamolay

    Joined:
    Jun 24, 2013
    Posts:
    43
    Hi, I was wondering if you could advise me on the best approach to rotating the character to the same direction as the plane they're currently on. (e.g. if the slope is 45 degrees, the characters up direction is also 45 degrees so they're perpendicular to the platform). I've been playing around with a few approaches but I seem to keep running into issues.

    When I rotate the character to the GroundNormal value, the player rotates to match the platform they're on. However if the player is over a ledge, the normal is incorrect, looking more like an average value of the two sides of the mesh. This seems to be a feature of the capsule cast method, it doesn't return a regular normal, and using this method causes the character to rotate around a ledge rather than fall off it.

    Secondly, when going up a ramp, the character should rotate to the platform its currently on, but as it rotates, the capsule then touches the previous platform and tries to rotate to suit that too as it's now counted that as the closestHit. This results in the capsule stuttering back and forth between the two surfaces trying to align itself to one. In this scenario, ideally what I'd like it is for the character to smoothly move between the two surfaces by possibly using the average normal of all the colliders it's touching.

    I think these problems are stemming from the capsule cast method rather than a raycast method, and I was wonder what would be the best approach to solve this problem? I don't mind if they method is a bit more expensive than the usual one, as long as I can get the job done. Hopefully I explained this OK, let me know if you need clarification :D
     

    Attached Files:

  10. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    That would be inside "ExamplePlayer". In the Update(), if moveAxisRight > 0, it means the player is holding right. If < 0, the player is holding left. Right now it doesn't have the notion of holding both at the same time, but this is simply an example and you are encouraged to create your own custom "Player"-style class (or put input handling directly in your character class, if you prefer that)
     
  11. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    You should try to make sure all rotations are done in UpdateRotation() if you want everything to work properly and without stutters.

    In your case, you seem to basically want no rootmotion for the rotation, but rootmotion for the movement. To accomplish this, you can take inspiration from the UpdateRotation() code of the basic movement walkthrough section for looking to a specific target, and leave the UpdateVelocity() code of the rootmotion section for moving with rootmotion
     
    Last edited: Jan 22, 2018
  12. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    I understand the problem, and it's true that this issue comes from the fact that the ground normal is detected by a capsule-cast. However, the solution to this problem should be simple enough.

    For this, I suggest you use 4 downward raycasts around the character's ".GroundPoint" to detect the average normal of the ground, and set your rotation to that (maybe with some smoothing). It work well in the case of ledges too, because for example 2 of them would detect an upward normal, and 2 would detect nothing at all. The average would still be perfectly upward. And just to clarify, the regular .GroundNormal would still be detected by the same old capsulecast. You'd just be adding raycasts for rotation

    They did this 4-rays technique in Horizon Zero Dawn to match the character animations to the ground elevations, although the "movement code" still just used the regular ground normal from the capsule cast. It would work nicely for your use case
     
    Last edited: Jan 22, 2018
    Guacamolay likes this.
  13. Guacamolay

    Guacamolay

    Joined:
    Jun 24, 2013
    Posts:
    43
    Thanks this technique does work well, and solves both problems I was having with the capsule cast! The controller is great by the way, I'll leave a review when I get a bit more in depth with it but I can see myself using it on most projects from now on!
     
  14. Ellernate

    Ellernate

    Joined:
    Aug 25, 2017
    Posts:
    81
    Thanks, this is an excellent character controller replacement. Sadly our game requires a bit of physics simulation on both client and server so I'll have to stick with the rigidbody controller for now. Will definitely take a second shot at implementing reconciliation after the next update.
     
  15. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    The behaviour you describe sounds as though HandlePhysics is set to (false, false/true). Do you call it at any point?

    Also, are there any errors or warnings popping up?

    And finally, what unity version are you using?
     
  16. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    I see... is your mesh collider in convex mode? If not, could you verify if the problem is still there for convex mesh colliders?

    And how many vertices does it have, roughly?

    Edit: I saw your PM, we can continue the conversation there if you want
     
    Last edited: Jan 26, 2018
  17. MikeFish

    MikeFish

    Joined:
    Oct 24, 2015
    Posts:
    12
    Hey there, got a question (again, sorry):
    So, I want to implement ledge handling, like when you just walk over a ledge the character grabs the ledge and is hanging there. I see that there is ledge handling somewhere in the kinematic motor class, but I can't figure out how to implement it. I also implemented wall jumping and every time i walk over a ledge the character switches to the wall jumping behaviour with having a jump direction of the ledge's normal.
    as short hint would be right, if I have to come up with a custom solution for this, or if there is something like standingOnLedge == true?
     
  18. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    The "Ledge handling" in KCC represents something different than what you describe. Ledge handling in this case is just proper velocity management when standing on ledges. It doesn't do much, but I've added it as an option because it costs two raycasts per update (which are reused for step handling too).

    Here's a demonstration:

    With ledge handling
    https://i.gyazo.com/8c2a01469054f0f66d6f5030c1e8caad.mp4

    Without ledge handling
    https://i.gyazo.com/6c454f0b29a11c3077f153ef36a56d4f.mp4

    Notice how without ledge handling, the character doesn't "launch" off of the ramp in a parabollic curve, but instead keeps snapping to the ledge ground as it moves off of it

    _____________________________________________________________

    As for the kind of ledge handling you are talking about; well let's just say it is a complicated thing to implement. It's also very specific to the particular behaviour you want for your game, so it's hard to come up with an "all-purpose" ledge handling.

    A good start for implementing this would be the "climbing ladders" section of the walkthrough. It is fairly similar to what you'd have to do. Basically, you'd turn off the character controller so that none of the collision handling logic interferes with what you're trying to do, and you just control the movement of your character object in an absolute manner
     
  19. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    Version 2.0 has been submitted for review to the asset store team! Expect it to land on the store in a near future
     
    Guacamolay and Ellernate like this.
  20. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    Are all changes still only in kinematic motor etc?
    with only slight api changes when inheriting from BaseCharacterController?

    What has changes for 2.0?
     
  21. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    The changes are pretty massive and I'll write a proper release notes post once it lands on the store (in the meantime, this post details some of those changes).

    However the changes you guys will have to make to your character controllers should be pretty manageable. Things have been renamed to shorter names (KinematicCharacterMotor.CharacterTransform -----> Motor.Transform), grounding info is now all contained in Motor.GroundingStatus, which is a struct, and a few method signatures have changed. I've made an Upgrade Guide here. A full replacement of all the Core components will be required, though (and of the Example/Walkthrough stuff, if you kept them in your project)
     
    Last edited: Jan 31, 2018
    Shinyclef likes this.
  22. ryanflees

    ryanflees

    Joined:
    Nov 15, 2014
    Posts:
    24
    Sorry my English is not good.
    Hi I'm trying to make a FPS framework with this plugin.
    What worries me is that I found that you put the character updates in FixedUpdate() of KinematicCharacterSystem.
    I used to use Update() for first person look with camera, so the control would feel much smooth and accurate.
    While with FixedUpdate() control becomes greasy and laggy.
    I'm still quite noob with deeper level of Unity. So I just want to ask why we should use FixedUpdate() instead of Update() in the Kinematic.

    And here is pretty much my strategy, Mouse Y controls the vertical rotation of the camera which is a child object of character, Mouse X controls the horizontal rotation of the character which is now being updated in FixedUpdate making the rotation quite greasy. I may try to find a workaround to rotate the camera with Mouse X as well instead of rotating character.
     
    Last edited: Feb 1, 2018
  23. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    FixedUpdate is used so everything is in sync with the physics updates.
    That's ok because changes to the Rigidbodies get interpolated over the frames inbetween as well, that's why it works just fine.
     
  24. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    While the character moves on FixedUpdate in KCC, the camera moves on Update for frame-perfect movement.

    FixedUpdate movement for the character gives you many advantages:
    • Better for interaction with rigidbodies
    • Essential for moving platforms
    • Essential for proper networking
    You actually can make the character run on Update easily in the upcoming 2.0 update since you can call Simulate() manually, but I really don't recommend it.

    _________

    As for your camera being rotated by parenting to the character, I think you should use a different strategy. It should be rotated directly by script to where you need to look, and the character should be rotated to that direction separately. With a naive implementation of this, you may notice that the character's rotation will be lagging behind the camera's (due to being FixedUpdate), but in the next update there is a tutorial on how to fix that. It basically involves rotating the character's 'mesh root' on Update, while leaving its physics rotation on FixedUpdate
     
    Last edited: Feb 1, 2018
  25. thestrandedmoose

    thestrandedmoose

    Joined:
    Jul 21, 2015
    Posts:
    70
    Hey Phil, I know your walkthrough doesn't get into character animation and stuff, but I was wondering if you know of any good resources/tutorials for a beginner to start integrating animations into your controller?

    I've already modeled and rigged my character in Maya using this tutorial (see below) but I'm not really sure where to go from here.

    Any advice you (or any other ppl following this thread) could provide would be much appreciated. Thanks!

     
  26. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    Animation is a pretty big subject. For a start, you need to make an important decision first:
    1. Do you want your animation to drive the character's movement? (this is known as rootmotion)
    2. Or do you want your animation to simply match the character's movement?
    There are advantages and disadvantages to both methods, and it depends a lot on the kind of game you are making. Games like Assassin's Creed will often be more root motion-driven, while more arcady games will take option #2. Root motion makes your animation always match movements perfectly, but it often results in slow, unresponsive controls.

    I suggest you start with something simple like this for example:
    https://unity3d.com/learn/tutorials/projects/adventure-game-tutorial/player?playlist=44381
    And just work your way up from there
     
    thestrandedmoose likes this.
  27. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    KCC v2.0 is now live on the store!

    ______________________________________________________________________

    Release notes:

    Large-scale refactor, cleanup, improvements and correction of minor bugs
    Over the last few months, I went through all of the major components of KCC and did a massive cleanup in order to simplify things. While doing this, I found tons of minor things to fix, remove, or optimize. The code is now much clearer, more robust, and better organized than before.

    Notable performance gains
    The estimated per-fixed-frame cost of one example character moving around on a box collider, with all quality options turned on, has gone from 0.038ms in v1.2.2 to 0.019ms in v2.0, which is essentially half of the previous cost.
    This was tested on my Intel Core i5-4690k in a Unity 2017.3 build with 1000 moving characters and no rendering camera. I found out the average total frame time of a FixedUpdate frame, and divided it by 1000. So this estimate really takes everything into consideration, and is actually a bit pessimistic.
    The character cost with all quality options turned off has stayed about the same as before (0.014ms). Notice that the difference between low-quality and high-quality isn't that big anymore, or at least not for the common case of moving on a flat surface.

    Improved collision resolution
    "Safe movement" used to be required in order to avoid tunneling through colliders in very acute corners (the corridors in the example scene). Now, due to improvements made to the base movement algorithm, the character controller handles that case well even when "Safe movement" is turned off (though for some reason, that is only the case for 2017.2 and up).
    KCC v1.2.2 (Safe Movement off):
    https://i.gyazo.com/e3aa09c6c642d98a34243621222c12cf.mp4
    KCC v2.0 (Safe Movement off):
    https://i.gyazo.com/9d2f7b8d637d5ef37262e455564bb33b.mp4

    Complex step-handling
    Users now have 3 options for step handling:
    - None: Can't step on anything unless the impact normal happens to satisfy our max slope angle needs. Better for performance
    - Simple: The original step handling method. Max step height is limited to capsule's radius
    - Complex: The new step handling method that isn't limited by capsule radius https://i.gyazo.com/b175837ede311e7cf89acfcbd5fbf3ca.mp4

    Custom interpolation
    A rigidbody interpolation bug since Unity 2017.2 has been making all interpolated movement stuttery in some circumstances. To counter this, KCC now uses a custom interpolation method by default. However, if you wish, you can go back to the old Unity interpolation method by setting the KinematicCharacterSystem.InterpolationMethod variable through scripting.
    Note1: Custom interpolation is a little bit heavier on performance than Unity rigidbody interpolation (probably due to not being multithreaded, but this might change once the Job System lands). This may affect your choice of interpolation method.
    Note2: According to Unity, the estimated time for the interpolation stutter fix is 2018.2 or 2018.3

    Ability to give the capsule an arbitrary center
    A user pointed out a situation where rotating the character's up direction really fast towards an opposite direction often resulted in the character ending up "under the floor", due to its pivot being at its feet. To solve this problem, the capsule's center can now be placed anywhere on the Y axis

    Walkthrough article on frame-perfect rotation
    Several people have asked about how to deal with the fact that the character operates on FixedUpdate while preserving highly-responsive rotation that doesn't lag behind. To better explain how to deal with that, a walkthrough article called "Frame-perfect rotation" has been added.

    Exposed manual control over simulation
    To help with networking implementations, several parameters and methods have been added to KinematicCharacterSystem:
    - AutoSimulation: Is true by default, but when set to false, it allows you to call the simulation manually. Works pretty much the same as Physics.autoSimulation
    - PreSimulationUpdate(): Call this at the very beginning of a simulation frame to remember what poses your characters should be moving from (will be useful later)
    - Simulate(): Call this to "tick" the simulation once and make all characters calculate their movement. You may call SImulate() several times between PreSimulationUpdate() and PostSimulationUpdate() if you want to resimulate past inputs.
    - PostSimulationUpdate(): Call this at the end of the frame to tell all system actors to move physically from the poses saved in PreSimulationUpdate, to their destination poses in the simulation

    See the contents of KinematicCharacterSystem.FixedUpdate() if you want an example of what you need to call in order to simulate.

    Ledge handling moved to custom character controllers
    Previously, ledge handling parameters (MaxStableDistanceFromLedge, etc...) were part of KinematicCharacterMotor. Now, a change has been made to give you more control over this, and so the implentation will have to be part of your character controllers. See how MaxStableDistanceFromLedge is now implemented in ExampleCharacterController for more details. (you can most likely just copy this implementation into your custom CC and it should work)

    GetState, ApplyState, SetPosition and SetRotation
    GetState and ApplyState returns or applies a "KinematicCharacterMotorState" struct that represents the state of a KinematicCharacterMotor that is pertinent for simulation (pos, rot, velocities, grounding, etc....). Use this to save the state at a specific time, or apply a past state instantly.
    SetPosition and SetRotation sets the character's position/rotation instantly, in the correct way, and without interpolation. This is used internally by the ApplyState() method, but can be useful on its own nonetheless

    MovePosition and MoveRotation
    You can now move your character with these instead of relying on UpdateVelocity and UpdateRotation. Full collision handling and movement projection will be applied when using them. However, I would suggest sticking to UpdateVelocity and UpdateRotation most of the time because they properly return the projected velocity.

    New Doxygen API reference

    The API reference has been moved out of the User Guide and into its own complete HTML documentation (available in a .zip file with the package)

    Upgrade Guide
    With all the changes made, there will be a bit of work to do for converting your existing character controllers. All of that is detailed in the Upgrade Guide (available in the package)
    https://drive.google.com/open?id=1so_WhbE_sYj0BaSxnEy2Va2Rc_KFYC6_qAWvlY51p24

    ______________________________________________________________________

    What's next?

    With this massive update out of the way, I can finally go back to the networking example. Version 2.0 solves tons of common user problems, so I am confident it'll alleviate the customer support workload too, and give me more time to focus on development.

    PS: I will do my best to make updates that are easier to swallow in the future! This was the first major update after getting a lot of serious customer feedback, so that might explain why it has so many changes
     
    Last edited: Feb 2, 2018
  28. maxaud

    maxaud

    Joined:
    Feb 12, 2016
    Posts:
    162
    Thanks for the hard work on this and pushing out a thorough update with lots of great content.

    I'm using option 2.

    I've been battling trying to wrap my head around properly animating my character. I have a fixed camera and the character moves around the level without being followed by the camera so I extrapolate the vector based an angle from camera and input from a joystick. I have the character moving around properly and pointing the direction I want them to aim based on input from a second joystick but cannot seem to figure out animating. I figured I should probably drop my past method of animating based upon input and base it upon polling the current vector and rotation and changing my animator values that way so it can easily be used for AI (who don't have controller input) as well but I can't seem to make it work. Especially when it comes to strafing. My animation controller is all set up and ready to go but having a hard time finding the best way to find the best velocity values and directional values.

    Any suggestions?
     
  29. ryanflees

    ryanflees

    Joined:
    Nov 15, 2014
    Posts:
    24
    ---------------
    Thanks for the reply.
    I'm now using a workaround and it works good.
    Since it's a first person game, the player contents(weapons/hands) doesn't necessarily be under the KinematicCharacterMotor object. I use a seperate player gameobject to contain camera+player models and update it as the same position of motor object which is only used for moving.
     
    Last edited: Feb 2, 2018
  30. JustinLarrabee

    JustinLarrabee

    Joined:
    Feb 3, 2013
    Posts:
    13
    Thanks for the updates!
     
  31. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,555
    So updated to 2.0 and it looks like it's making me now do logic that was handled internally before with the stability report stuff. Unless I'm misunderstanding it, why is it better to force me to do that? Now I have to work out the logic for a bunch of existing code that was using that and related info.

    Like for example. how am I supposed to now determine if I'm stable on ground?
     
  32. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,555
    Ah ok at first glance I thought the stability report had to be filled out to get grounding information. I now see it's just there to override
     
  33. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,555
    That said it looks like behavior is different also. if I set position via transform.position it seems to move it back to where it was previously.
     
  34. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    364
    Awesome. I'm very happy to see the pivot point and step height changes. The whole update seems excellent! Will try soon!
     
  35. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,555
    Ok so using the motor SetPosition works. Any direct updates to the transform are reset by the motor.
     
  36. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,555
    Something is off with Interpolation also. And I'm not liking at all the locking of components. That prevents doing custom stuff at runtime where I might have a good reason to remove the rigidbody (which I do).

    Edit: Actually the locking probably just came back because I think I had removed the RequireComponent stuff in the last version.
     
    Last edited: Feb 2, 2018
  37. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    I'd say using velocities for animation is probably a better option than using input. Like you said, it's better for AIs. If you'd need some kind of "rotation velocity" for animation, you can get that like this:
    Code (CSharp):
    1.  
    2.         public override void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
    3.         {
    4.             Quaternion initialRotation = currentRotation;
    5.  
    6.             // ...
    7.             // Modify currentRotation here
    8.             // ...
    9.  
    10.             Quaternion rotationFromLastToCurrent = currentRotation * Quaternion.Inverse(initialRotation);
    11.             Vector3 rotationVelocity = rotationFromLastToCurrent.eulerAngles / deltaTime;
    12.         }
    13.  
     
  38. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    That's right. SetPosition and SetRotation must always be used now instead of setting the transform directly

    Can you describe the interpolation problems you're seeing?
     
  39. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    It'll be difficult to tell what the problem is without seeing the code for your character controller. Or do you also see this problem in the current walkthroughs?
     
  40. maxaud

    maxaud

    Joined:
    Feb 12, 2016
    Posts:
    162
    I'm not using any rotation animation as my character simply points where they are moving/aiming to but I'm having an issue with determining the correct relative velocity for the character on two axis' as I am using a 2D blend tree for strafing IF the player is using the 2nd joystick to point the character a different direction then he is moving.

    I'm sure this quiet an amateur mistake.
     
  41. thestrandedmoose

    thestrandedmoose

    Joined:
    Jul 21, 2015
    Posts:
    70
    Thanks for the update Phil! And for the unity link. I'll check it out
    I think I will be animating for option #2: Seems like it would be a bit simpler and probably easier on the processor

    Thanks again!
     
  42. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,555
    It was interpolate not set on rigidbodies. But I can't remember if that is because I set it manually in the editor since I removed the locks on rigidobodies, or if the interpolation setting was there in the last version in KinematicCharacterSystem and I just didn't see it (using it now).
     
  43. VagabondOfHell

    VagabondOfHell

    Joined:
    Sep 17, 2013
    Posts:
    11
    Hi PhilSA

    This isn't an issue with the package at all, so if you don't answer it, I totally understand.

    That being said, I was wondering if you could help me with rotating the capsule underwater. I've been following your walkthrough (very easy to follow!) and got up to the swim part with my own custom additions to parts, as well as using your OrbitCamera as a first-person view.

    I'd like to rotate the capsule so essentially the capsules 'up' is along the 'forward' instead, so that you can swim in narrow passageways. I know I'm missing something super small.. just can't seem to get it just right. The closest I've gotten is:


    currentRotation =
    Quaternion.FromToRotation((currentRotation * Vector3.up),
    Quaternion.AngleAxis(90, currentRotation * Vector3.right) *
    AssignedCharacterController.TargetLookDirection);

    But I've tried a hundred permutations. Mostly using the gravity orientation sample as a base. Clearly quaternions are not a strong point of mine. This one ends up with sudden flips at certain directions and freezes rotations along the up axis.

    I appreciate any help on the matter. Thank you for this fantastic product nonetheless. Best asset store purchase I've made yet!
     
  44. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    you could get that velocity like this:
    Code (CSharp):
    1. Vector3 planarVelocity = Vector3.ProjectOnPlane(Motor.BaseVelocity, Motor.CharacterUp);
     
    maxaud likes this.
  45. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    #2 is my preference too. Rootmotion is pretty popular among AAAs for a long time, but recently it's been rapidly losing popularity in favor of the #2 approach, because it is much more responsive and advances in procedural animation has been improving the "matching" of movement and animation so much that rootmotion isn't worth it anymore.

    Rootmotion can quickly become hell to manage
     
  46. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    This is due to the new Custom Interpolation, which skips rigidbody interpolation entirely (because of the stutter bugs in Unity) and handles it in a completely separate way
     
  47. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    I thought it'd be interesting to try to implement this in my swimming example, so here's what I came up with so far (see attachment). The only part that's different is in UpdateRotation(). Just replace the current MySwimmingState with this one

    It doesn't solve the problem of the camera, and it causes weirdness when trying to move back on land, but I think it does solve the rotation problem. The character always "leans forward" towards its movement direction while swimming.

    I'll have to take more time eventually to solve the problems I just mentioned and make it more polished, but it's a start

    EDIT: In OrbitCamera, if you replace all instances of "FollowTransform.up" by "Vector3.up", it solves the camera problem while swimming. I'll try to figure out a way to make this more versatile so that users don't have to change the actual script
     

    Attached Files:

    Last edited: Feb 3, 2018
  48. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    364
    Hello, I've run into a little problem using the new complex step/ledge logic.
    I have a feeling it's a bug in my own code somewhere as I wasn't able to reproduce it on your example scene.
    I also have a feeling it's related to ledge detection but I'm not sure.

    When jumping up a block, the character kind of jolts up if there is a ledge that it may be able to reach.
    Take a look at the attached video to see what I mean. It doesn't happen if I look away from the wall, and it doesn't happen when the wall is sufficiently high, like the first 2 jumps in the video.

    Those blocks are 1 unit high, and my max step height is set to 0.501.
    I copied your new code from ProcessHitStabilityReport.
    In case it helps, I've attached my DefaultMovementState script.

    Anything obvious come to mind?

    Edit: More useful findings:
    With step height set to 0.44, the bug does not occur in simple step/ledge mode. It does occur on complex step/ledge mode.
     

    Attached Files:

  49. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,257
    Just to be sure - can you check if it has anything to do with the blocks you've removed in the video? Does it still happen on short walls that were always short?

    I don't see anything suspicious in your code so far
     
    Last edited: Feb 3, 2018
  50. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    364
    It only seems to be happening with my game's blocks, you're right.
    Attached is a new vid that shows how I tested, and also shows a lot more about what's going on with my game's physics. The white wall is a simple box that is larger.
    I guess this means the problem presents when the adjacent wall is made up of stacked box colliders.
     

    Attached Files:

unityunity