Help with movement using acceleration

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);

}

Use code tags, this is barely readable.

This…

velocity *= Mathf.Pow(damping, duration);

Is an incredibly bad idea, because judging by the code snippet you posted, damping appears to be a static value, and if it is true, then damping does not take Time.deltaTime into account (amount of time passed since last frame).

Basically, if damping is fixed value, then higher FPS will make your character lose speed faster.

To cap speed and allow acceleration at max speed, simply hard cap maximum velocity. For example.

var linearVelocity = velocity.magnitude;
var maxVelocity = ....//some value

if (linearVelocity > maxVelocity){
    velocity *= maxVelocity / linearVelocity;
}

And then allow non-zero acceleration at max speed.

It also depends on what sort of controller you’re designing. For example, a hoverbot would likley treat accelerations on different axes separately. Meaning, going at max speed on x axis, would still allow max acceleration on z axis.

On other hand, if you’re trying to simulate some sort of dash, then higher speed would reduce opportunity to turn, meaning it will cap linear acceleration based on linear speed.

How would you recommend doing damping I referenced a book on game physics and it said I could set a damping value and raise it to delta t power and that would be good enough instead of deciding the magnitude for a drag force or something. Ill also try out the hard cap velocity

You’ll have to experiment and find what works for your game.

However, no matter what you do, it should take delta time into account. Otherwise FPS will affect gameplay.

Simply linearly decreasing speed is an option. Trying to use damping functions from unity Vector3 and Mathf moduls is an option. Drag force is an option.

You can also modify your original formula, and turn “damping” to “damping per time interval”. In this case damping can be computed as Mathf.Pow(damp, time.deltaTime/timeInterval), for example.

for the timeinterval in the mathf.pow call would that be a static number as you already call time.delta time