I am using unity’s character controller.move by giving it a delta position to move. This is arrived at first getting the acceleration multiplying it by delta time then adding it to velocity. Then delta position is just velocity times delta time. Also on velocity i have damping so it gets multiplied by the damping value (0.9f) to the power of delta time. All is well. Then I have a linked list that i go through where each node checks the velocity and returns a specific acceleration to accelerate at. I do this so i can accelerate quickly to a velocity then accelerate slowly to max speed allowing acceleration to feel somewhat responsive. The problem with this system is turning as it works well going in a straight line however it won’t move side to side or diagonally at all since acceleration is 0 at top speed. I tried fixing this by instead of checking the raw velocity number i have it projected onto my input direction with Vector3.project so we are basing the acceleration based on how much velocity we have in the desired direction. This allows turning however acceleration to the direction is inconsistent and can use the quick acceleration causing fast changes in momentum or the slower one resulting in unresponsive controls.
Is there a better way to go about using different accelerations at different speeds or moments and still have responsive and consistent movement or is there a fix to my system that could help me? If not is there a source you can link or send me too that creates a character controller that moves with acceleration and preferably the acceleration differs at different speeds (doesn’t have to have this)?
Heres my integrate function which does the physics calculations
private void IntegrateLinear(float duration)
{
positionDelta = velocity * duration;
Vector3 resultingAcc = acceleration;
velocity += (resultingAcc * duration);
velocity *= Mathf.Pow(damping, duration);
SetAcceleration(Vector3.zero);
}
And heres the linked list traversal thing that adds the acceleration based off the returned acceleration
if(sprint){
AccActions.TryGetValue(“sprint”, out int index);
AccRange ptr = AccLinkedLists[index];
Vector3 velProjected = Vector3.Project(groundedVel, inputDir.normalized);
while (ptr != null)
{
if (ptr.check.Equals(“velocity”))
{
if (ptr.CheckRange(velProjected))
{
sprintAcc = ptr.GetAcc();
break;
}
else
{
ptr = ptr.next;
}
}
AddAcceleration(inputDir * sprintAcc);
}