I’m trying to write a basic character controller without having to rely on Unity’s built in solution as an opportunity to learn and create a more robust system for use in the future. However, I can’t escape a bug with my current implementations.

Here is the code I’ve made for a basic ‘collide and slide’ algorithm, and in my head and on paper this works fine but my controller consistently either gets stuck or clips right through walls when in practice.

Is there anyone out there with a similar problem? Am I missing something crucial? any help is welcome.

code :

// bias = 0.05f;

void Move(Vector3 velocity)

{

Vector3 position = transform.position;

Vector3 trajectory = velocity;

int bounces = 0;

while (trajectory.magnitude > minMoveDistance && bounces < 5)

{

if (charCol.CapsuleTrace(position,trajectory,transform.rotation,validLayers,

hitBuffer,QueryTriggerInteraction.UseGlobal,bias))

{

float hitDistance = charCol.GetClosestHit(hitBuffer).distance;

float fraction = (hitDistance/trajectory.magnitude);

position += hitDistance * trajectory;

trajectory *= (1-fraction);
for (int i = 0; i < hitBuffer.Length; i++)
{
RaycastHit thisHit = hitBuffer*;*

*if (thisHit.distance == 0) break;*

*Vector3 projected = Vector3.ProjectOnPlane(trajectory,thisHit.normal);*

*trajectory = projected;*

*}*

*}*

*else*

*{ break; }*

*bounces++;*

*}*

*transform.position = position + trajectory;*

*}*

*public bool CapsuleTrace(*

*Vector3 position,*

*Vector3 direction,*

*Quaternion orientation,*

*LayerMask validLayers,*

*RaycastHit[ ] hitBuffer,*

*QueryTriggerInteraction triggers = QueryTriggerInteraction.UseGlobal,*

*float bias = float.Epsilon // Common to set this to at most 1% of capsules radius. Epsilon for default.*

*)*

*{*

*position += orientation * capCol.center; // Orient position with rotation of body.*

*capsuleLineSegment = orientation * Vector3.up * ((capCol.height / 2) - (capCol.radius));*

*int traceHits = Physics.CapsuleCastNonAlloc(*

*position + capsuleLineSegment,*

*position - capsuleLineSegment,*

*capCol.radius + bias,*

*direction.normalized,*

*hitBuffer,*

*direction.magnitude,*

*validLayers,*

*triggers*

*);*

*if (traceHits > 0) return true;*

*return false;*

*}*