I noticed this was occurring in the RPG course also. I spent some time looking into it and found that under the right conditions the raycast which comes out of the bottom of the model to determine whether the model is on the ground or not doesn’t quite work as expected.
The raycast has an original that is ever so fractionally within the character, if the origin of a raycast is actually inside another collider it won’t report it. What I observed was that often, on ground that was not flat, the origin of the raycast would not report back and as such the code set it to be “falling”… this gave the look of the invisible motorbike rider / sliding model. There was also a condition where by the character would jiggly / twitch / move uncontrollably when it should be stationary. This turned out to be related but was due to the animation actually moving the character and some conflicts between the code.
I don’t know whether it will fix your issue, but I tweaked the code in both the ThirdPersonCharacter.cs and AICharacterControl.cs scripts and was able to resolve the issue completely - at least within the confines of the testing I was doing. Below are the snippets from each of the two files which I had changed;
AICharacterControl.cs
private void Update()
{
if (target != null)
agent.SetDestination(target.position);
else
character.StopMoving();
if (agent.remainingDistance > agent.stoppingDistance)
{
character.Move(agent.desiredVelocity, false, false);
}
else
{
target = null;
character.StopMoving();
}
}
ThirdPersonCharacter.cs
[Space][Tooltip("Minimum value 0.1f")][SerializeField] float m_GroundCheckDistance = 0.1f;
/// <summary>
/// Stops the character moving
/// </summary>
public void StopMoving()
{
// TODO: should maybe consider checking whether we are moving first
CheckGroundStatus();
Vector3 stop = Vector3.zero;
m_TurnAmount = Mathf.Atan2(stop.x, stop.z);
m_ForwardAmount = stop.z;
UpdateAnimator(Vector3.zero);
}
void CheckGroundStatus()
{
// increased offset from 0.1f to 0.5f to place origin of raycast further inside the character
float rayCastOriginOffset = 0.5f;
RaycastHit hitInfo;
#if UNITY_EDITOR
// helper to visualise the ground check ray in the scene view
Debug.DrawLine(transform.position + (Vector3.up * rayCastOriginOffset), transform.position + (Vector3.up * rayCastOriginOffset) + (Vector3.down * m_GroundCheckDistance));
#endif
// rayCastOriginOffset is a small offset to start the ray from inside the character
// it is also good to note that the transform position in the sample assets is at the base of the character
if (Physics.Raycast(transform.position + (Vector3.up * rayCastOriginOffset), Vector3.down, out hitInfo, (rayCastOriginOffset + m_GroundCheckDistance)))
{
m_GroundNormal = hitInfo.normal;
m_IsGrounded = true;
m_Animator.applyRootMotion = true;
}
else
{
m_IsGrounded = false;
m_GroundNormal = Vector3.up;
m_Animator.applyRootMotion = false;
}
}
Not sure if it will help but thought I would share on the off chance.