A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate
in the Unity community.
Discussion in 'Assets and Asset Store' started by PhilSA, Sep 29, 2017.
KCC 3.2.0 is submitted for review. Expect it to land on the store in a few days
EDIT: it's there now
I'd happily pay again for a DOTS version too. Or even just breaking changes where you move more of the code away from Monos and silo it so interactions with physics are more controlled.
I don't think you should feel bad for not working the forum thread. There are plenty of wonky assets on the store where the author kills themselves trying to answer every dumb question and that's kind of their angle. Their code isn't very good, but they try to make up for it by helping people navigate it.
Your code is very good and you are clear this is meant for programmers. I am very happy to pay for good code rather than good support. I think you should just update the description to make it even clearer that no one should necessarily expect support. They get the code as is and if you have time you'll try to help on the thread but there are no expectations.
I also think you are doing more than fine enough when you give people vague help and not necessarily any code. Earlier in the thread you gave me an idea how I should go about implementing something and I was very happy to get that. I wouldn't expect you to spend hours implementing it for me and it saved me time to know how the code's author thought it should be done.
Hi guys, what do you think would be the best way to implement fall damage? I couldn't find any mentions of it here in this topic, nor in the docs
Walkthrough has a section on detecting landing. You can save a "last frame velocity" somewhere and apply a multiplier to that whenever a landing is detected to determine damage. You might also was to project that velocity on character up so you get just the vertical velocity
Talk About DOTS version, maybe you can make its core open source, and sell feature modules in asset store (also open a door for others to make stuff like UMA)
hi, when character jump and hit something(an irregular object, such as a tree mesh collider) in air, i found the character will beat back then i can't controller it , it let the player very hard to controller the character, how can i change it?
Try increasing air acceleration for more in air control
i struggle with a Proglem. I do the walkthrough "Jumping" and want to change the behaviour. The example can jump on obstacles and uses the current velocity to "climb" a little bit up. Even if the obstacle or especially then the ground is not stable.
Now i dont want that. I want to stop the player whenever he hits an object and then applying the gravity so he just falls down and dont climb on a steep sloping wall. Check out the Picture i attached. I thought i can just set the current velocity to zero when the motor detects an unstable ground. But it gets called every frame so the currentvelocity will also be set to zero every frame. Right now i dont know how to fix that. The next thing is - what if i hit an obstacle and the motor does not see the obstacle because its too steep? then i will also start "climbing" again...
thank you for every help...
here is the original code snipped of your example character in the walkthrough
// Add move input
if (_moveInputVector.sqrMagnitude > 0f)
targetMovementVelocity = _moveInputVector * MaxAirMoveSpeed;
// Prevent climbing on un-stable slopes with air movement
Vector3 perpenticularObstructionNormal = Vector3.Cross(Vector3.Cross(Motor.CharacterUp, Motor.GroundingStatus.GroundNormal), Motor.CharacterUp).normalized;
targetMovementVelocity = Vector3.ProjectOnPlane(targetMovementVelocity, perpenticularObstructionNormal);
Vector3 velocityDiff = Vector3.ProjectOnPlane(targetMovementVelocity - currentVelocity, Gravity);
currentVelocity += velocityDiff * AirAccelerationSpeed * deltaTime;
currentVelocity += Gravity * AirAccelerationSpeed * deltaTime;
currentVelocity *= (1f / (1f + (Drag * deltaTime)));
you can accomplish this like so:
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport)
if (!Motor.GroundingStatus.IsStableOnGround && !hitStabilityReport.IsStable && Vector3.Dot(Motor.CharacterUp, Motor.BaseVelocity) > 0)
Motor.BaseVelocity = Vector3.ProjectOnPlane(Motor.BaseVelocity, Motor.CharacterUp);
In other words, when we are in air and we hit something we can't be grounded on, and our velocity is going up, cancel out the upward part of the velocity by projecting it on our characterUp plane
Thanks for the update!
This may be too complicated a question but, I wanted to implement some kind of Swinging mechanic into this character controller, but I have no idea where to start.
Something like the Purple Lum Swinging in Rayman 2 0:57
The problem consists of setting your character's velocity so that it mimics a ball socket joint of a given length (the rope) attached to a certain point
Blue is the rope
Yellow is your character's in air velocity with gravity as it would be applied normally
Red is how it should be projected every frame to do the ball socket logic
So at every UpdateVelocity where you're swinging, do the regular in air movement handling, but project the final velocity (after gravity was applied) on the character-to-rope-point plane normal. It should give you a swing that feels physicsy. So:
currentVelocity = Vector3.ProjectOnPlane(currentVelocity, characterToRopeAttachPoint.normalized);
you might also want to correct the character's position directly every frame so that it doesn't ever drift further away from the anchor point than the rope's length, with Motor.SetPosition(). Or, you could correct the projected velocity (in red) after calculating it, so that it always brings you exactly on the swing circle over the next frame. Basically, you take the final worldspace point of where the velocity would bring you on the next frame, calculate its distance to the swing anchor point, and displace it so that distance is exactly the length of the rope. You then reconvert that movement to a velocity by dividing with deltaTime, and that's your corrected velocity. Less risks of interpolation problems with this velocity approach
Thank you! thats exactly what i want. But can you explain me what the "hitStabilityReport.IsStable" means? In the API it just says "hitStabilityReport - Contains all the information from a hit stability evaluation" but i still dont know what a stability evaluation is. Maybe something simular to GroundingStatus.IsStableOnGround?
Edit: And what is the difference between Motor.BaseVelocity and the ref currentVelocity in the character controller? Does baseVelocity represent the actual current velocity and currentVelocity is just an variable that will be used by motor to set the baseVelocity?
It tells you if you'd be stable on that hit (as opposed to if you're stable right now)
They are the same thing. CurrentVelocity is just there to make it more clear what you should be modifying
Thank you again and sorry for another question. Its really hard for me to get behind the logic but i get ahead.
Right now i try to understand the code from the walkthrough "Frame Perfect rotation". Both objects, the parent CharacterController and the RootChild get applied the same rotation (because of the HandleRotation method). But why does the CharacterController keeps it rotation in the inspector (for example a rotation of 45degree) and the RootObject just get a temporal rotationchange when i move the cursor? Obviously the root object just need a small rotation to bridge over the delay of the fixed update but i dont understand how it works when both get the same rotation applied.
The code snippet:
public void PostInputUpdate(float deltaTime)
Quaternion newRotation = Quaternion.identity;
HandleRotation(ref newRotation, deltaTime);
MeshRoot.rotation = newRotation;
private void HandleRotation(ref Quaternion inputRotation, float deltaTime)
if (_lookInputVector != Vector3.zero)
inputRotation = Quaternion.LookRotation(_lookInputVector, Motor.CharacterUp);
public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
HandleRotation(ref currentRotation, deltaTime);
Heh, you should implement this into one small example scene, looks interesting^^
And yea, if one day you release a dots version, it should be not free. It can take up quite a bunch of time until this one will be usable in production and this work should get paid =)
I'm using 'A* Pathfinding Project' RVOController to do the pathfinding and RVO obstacle and agent avoidance. Does this seem like the proper way of forwarding the movement data from the RVOController to the KCC?
(The following code snippet is running inside a FixedUpdate method)
// Get a processed movement delta from the rvo controller and move the character.
// This is based on information from earlier frames.
Vector3 movementDelta = _rvoController.CalculateMovementDelta(Time.deltaTime);
Vector3 newPosition = position + movementDelta;
if (_rvoController.movementPlaneMode == MovementPlane.XZ)
if (Physics.Raycast(newPosition + Vector3.up, Vector3.down, out RaycastHit hit, 2f, groundMask))
newPosition.y = hit.point.y;
Vector3 currentCornerDirection = (newPosition - transform.position).normalized;
var inputs = new AICharacterInputs
MoveVector = currentCornerDirection,
LookVector = Vector3.ProjectOnPlane(currentCornerDirection, _characterController.Motor.CharacterUp)
float dt = Time.deltaTime > 0.0001f ? Time.deltaTime : 0.02f;
_characterController.MaxStableMoveSpeedCurrent = (movementDelta / dt).magnitude;
EDIT: Big reason for me asking is... what about the root motion example KCC? There is this part
currentVelocity = Motor.GetDirectionTangentToSurface(currentVelocity, Motor.GroundingStatus.GroundNormal) * currentVelocity.magnitude;
When using SetInputs (as I do in the above code when accounting for RVO and pathfinding), there is no 'GetDirectionTangentToSurface' method call. Should I rather set velocity directly and use the 'GetDirectionTangentToSurface' method when using RVO avoidance, pathfinding AND root motion as well? When and where to do what?
Sorry, I'm just lost in this a little
i'm new with the Kinematic Character Controller. But my first problem was, that i cannot make my controller stand still on a rotating plattform. the rotation is in x direction. the problem was, the character is always fall from the plattform. ofcourse i changed the gravity constantly. but the character doesn't stand still in the center. it is constanlty dragged to the edge of the platform.
Has the networking example been removed?
See the walkthrough section on how to setup a moving platform. You need a special component for it (PhysicsMover) and also a special script that controls the movement of the PhysicsMover
It was removed because it was an insane amount of work to maintain
I ended up building an entire example network framework (not one you could use in a real project) in order to demonstrate that KCC could be used for CSGO-style networking with rollback and prediction. It worked, but I really tried to bite off more than I could chew with that thing and I couldn't find the time to answer questions about it, so I took it down
You still probably want to use SetInputs when dealing with an AI character following a navmesh. The reason why the rootmotion example does things differently is because the velocity must be dictated by the animation; not the inputs. In the case of rootmotion, the inputs affect the animation, and the animation affects the velocity
SetInputs is only part of the "Example" character controller, though, so any other way you want to handle velocity is good too. But the reason why I like it is because when you SetInputs with a vector of magnitude 1, you're saying "Go at your max speed in that direction". So it's easier to move with that than having to calculate the desired velocity all the time. It hides a lot of the complexity
Here's why the jitteriness happens normally:
Usually, the camera rotates on Update for maximum fluidity
Usually, the character rotates on FixedUpdate because... complicated reasons. Let's say because it's physics
Since the character will update less frequently than the camera at high framerates, and since character movement is interpolated between fixed updates, the character rotation will always appear to "lag behind" camera movement a little bit
Now here's what "Frame Perfect Rotation" tries to do, conceptually:
On Update(), a mouse movement will make the camera rotate
On Update(), FramePerfectRotation will also make the child visual meshes of the character rotate to face the up to date camera direction
...so far, we have the camera and the mesh both rotated in perfect synchronization
On FixedUpdate(), the character physics rotates to face the camera
...this causes the child visual meshes to rotate again, because they are child transforms!
in the same frame, but after the FixedUpdate(), PostInputUpdate() is called again, setting the rotation of the child visual meshes again, and therefore fixing the extra rotation of the last step
To be honest, it would be waaaaay simpler if the character controller physics and the character meshes were just two completely separate gameObjects. The physics would rotate on FixedUpdate (or maybe it wouldn't even rotate at all, since a capsule rotating around its Y is still the same capsule), the meshes would rotate on Update(), and everything would be happy
also... you guys wanna see a sneak peek of DOTS Character Controller?
Now that's cheeky.
BTW, while you are at it, a little relevant to VR question:
it would be lovely to support moving the controller instantly in one frame *without* waiting and without disturbing current sim, that is, when a head collides with a wall, some VR games offset the camera, but this requires offsetting the controller at the same time by an opposite amount, and that's quite difficult for a system tied so strongly to fixed update, because there can be no delay or waiting in VR else the lag makes you feel sick.
So I was wondering if there's a way to do that instantly, because VR typically runs at really high framerates.
I think some testing would be required, but I can see 2 things that might work:
You can make KCC update on Update() by setting KinematicCharacterSystem.Settings.AutoSimulation = false, and have a monobehaviour somewhere call KinematicCharacterSystem.Simulate in its Update(). Only downside that comes to mind is that moving platforms probably won't work super well when it's not fixed update. And framerate spikes could make ground snapping fail sometimes
If you stay with FixedUpdate, you can still just offset the character instantly with Motor.SetPosition(targetPos, true). If it ever overlaps another collider as a result of that, it'll decollide on the next frame
Thanks that sounds reasonable
Re-posting from a few months ago:
Maybe I'm overlooking something, but when you add a Rigidbody object to the KCC's "IgnoredColliders" list - it's still possible to move the ignored object occasionally and seemingly only from certain angles.
Thing I tried:
I have this issue in my own project and was able to replicate it in the "playground" scene by using the blue rigidbody cubes (easier to test if you lower their mass).
I can also confirm that any non-rigidbody mesh added to the list is properly ignored
I tried configuring the KCC's rigidbody options in various ways to no effect
I think in this case, the character ignores the rigidbody, but the rigidbody doesn't ignore the character. So if you need to ignore rigidbodies, you would have to call Physics.IgnoreCollision(rigirbodyColl, characterColl) on top of the regular KCC ignore system
I was looking for fixes on the KCC end - adjusting the RB physics directly makes perfect sense.
Thanks a ton, Phil!
Thanks Phil! I think I got it working, I can definitely keep tweaking this to do what I have in mind.
Although I kinda got lost with that last part about finding the worldspace point of the next frame, and displacing it n such, so I'm just using the Motor.SetPosition() method for now.
blue represents the circular trajectory you should have while swinging
red is the velocity projected on the rope normal plane
orange is how the velocity should be corrected in order to compensate for position drifting
as you can see, the red vector will bring your character a tiny bit further away from the circle on every frame. This is what I mean by "drifting". So if you're swinging for 10 minutes without correcting the position, you'll probably reach the ground eventually
You can get the orange velocity vector by:
find the world position where the red vector would bring you over the next frame (nextPos = currentPos + (vel * dt))
find the green vector (anchorPointToNextPos)
nextPosCorrected = anchorPoint + (anchorPointToNextPos.normalized * ropeLength)
velocityToNextPos = (nextPosCorrected - currentPos) / dt
"velocityToNextPos" is the final velocity you should assign in UpdateVelocity
I think I got this working. I started a swing arc that swings extremely close to the ground to test it. I've been swinging around for awhile now and haven't gotten any lower so I think everything's good!
Thanks for your time, and for such a clear explanation!
hah nice... when is that coming, will we have to do much with DOTS..I'm not familiar with it at all
The ETA is very very very uncertain at this point, because it depends a lot on when DOTS itself will be "production ready" and will have settled on a final workflow. We're still far from that point.
Besides, I have yet to implement the big 3 complicated character features: Step Handling, Moving Platforms, and Ledge Handling. These should take me a while. Although they don't have a meaningful performance cost when the CC isn't actively on a step/ledge/platform, so the performance shown in the video should still be representative of the final one
And yeah, it'll be a CC that you can only use if -most- of your game is made in DOTS, since it relies on DOTS physics and requires you to "control" the velocity in DOTS
Also, just a fun little piece of info:
"b-hopping" or "strafing" in classic shooters happens for reasons that are very similar to what is explained here. Imagine your character is the anchor point, and your velocity vector is the blue rope vector. If you're advancing diagonally while rotating, your rotated velocity will end up looking a little bit like the green vector. It'll "drift" a little bit, meaning it'll grow beyond what was intended to be the max velocity every frame (beyond the blue radius, representing what the max velocity should be).
Basically, "strafing" was a happy accident. It's an unintentional bug that turned into a beloved feature
I dropped my muesli spoon when i saw the amount of other character controllers :O Amazing work! Will the Character Logic be the same or simular?
I'll start off with making it feel the same as KCC, but I'll experiment with improving interaction with rigidbodies once that's done
It seems this system assumes that the character is always facing at least semi upwards. If this is the case what exactly would happen in a scenario like this (Character aligns to normal)? Either way I'm very interested.
Emailed you earlier this morning and didn't receive any answer yet. So I figured I would try this channel as well...
We're looking at using your asset in one of our projects. However it's only 2019.2 and up compatible... Why not supporting earlier versions of unity? Do you happen to have a 2018.4.12 compatible? if yes let me know. I'll go ahead and place the order so that I can provide you with an invoice#.
Looking forward to your answer.
There should be no issues with 2018.4. None that I'm aware of at least, and if issues do come up, just let me know and I'm sure a quick fix can be made
The only reason why it says "2019.2+" on the asset store is because that's the main tested version
I think this is a case where you'd need a bit of game-specific code to achieve what you want. If we just naively orient on ground normal in a case like this, the transition from sphere to ground will probably look way too sudden and it'll feel wrong. Or maybe it wouldn't work at all, if physics queries decide that the sphere (a valid grounding) is detected before the floor.
What you'd probably want to do is to send a bunch of raycasts around your character to get an average nearby ground normal, and smoothly interpolate your character up towards that average normal
Horizon Zero Dawn does something similar (raycasts to find an average nearby ground normal) in order to anticipate big slope changes so that the animation can respond accordingly in advance
I tried testing your test scene and found a few issues:
not very important: teleporter is missing script to go onto the planet (easy fix)
very important: the planet gravity example looks pretty wrong: it doesn't look like the character has always its feet on the ground but if you go upside down then its head is touching the ground. The alignment seems wrong
tried to go to full speed and made a big jump when on the planet to see if I would be kept on the ground through gravity but I managed to fly off very very far and was still somehow under the influence of the gravitational field of the planet... went under the map etc ...
On unity 2018.4.12. Is it a known issue? did I miss something during set up / installation? if not do you have a fix? the rest of the map seems to play fine.
It's just about the Example Character Controller component settings. Set 'Bonus Orientation Method' to 'Towards Gravity'. This has changed from the previous version. It's just an example scene, so I guess Phil was just testing something there and forgot to change the setting. Also one more thing I can't now remember has changed. But again, you can fix it all by simply playing with the character controller inspector values.
Thanks you for taking the time to chime in!
I knew it was something simple
yeah, the planet gravity not working was something I forgot, like @Gooren said. I updated the package on the store last night to fix it (v3.2.1)
As for point #3, this is because my gravity implementation is overly simplistic. When you enter the teleporter to planet, the PlanetManager listens to teleporter callbacks. If you teleport to the planet, it starts controlling the character gravity, and if you teleport back to ground, it'll stop affecting character gravity. A real implementation would have a script checking the distance between character(s) and planet(s) and would set gravity on Update based on distance between character and planet (or something like that)
As for "teleporter is missing script to go onto the planet (easy fix)", I'm interested to fix this but I couldn't find it. Is it on this object?
Hey! Yep, this is the object that had the missing script in the test scene.
Hi, is it possible to create a moving platform without using a rigidbody?
My issue is that the collider the player is supposed to stand on is being moved over a spline, but the collider is (and has to be) a child of the actual object being moved. Adding a rigidbody results in the platform not being moved with its parent.
It's unfortunately not possible, but a workaround would be to have having an invisible object moving on the spline, and having the physicsMover be a totally separate object with a script that makes it follow the invisible spline object
(Not ideal, i know)
Thanks a lot! I'm doing something similar now, the rigidbody is still parented to the moving object, but in the platform script it just sets it position and rotation according to the parent which works well.