#Why is my velocity calculation so wildly inconsistent (using CharacterController)?

1 messages · Page 1 of 1 (latest)

spring aspen
#

I've made my character script, and in it I set my FixedUpdate like so:

void FixedUpdate()
        {
            previousFrameVelocity = transform.position - previousFramePosition;
            previousFramePosition = transform.position;
            
            if (stateMachine != null)
            {
                isGrounded = controller.isGrounded;                
                stateMachine.MovementInput(movementInput); // Send input controls into my SM
                Vector3 movement = stateMachine.FixedUpdate(); // SM outputs movement vector
                currentVelocity = stateMachine.ProcessVelocity(currentVelocity); //applying gravity
                Vector3 combined = movement + currentVelocity;        
                characterController.Move(combined * Time.fixedDeltaTime);
            }
        }

However, in the game, when I use previousFrameVelocity when my isGrounded state changes to see at which speed I impacted the ground, the results are infuriatingly inconsistent (and I've tried CharacterController's own .velocity, same thing, and a reason I went for explicitly calculating previousFrameVelocity in the first place), my logs show this after I moved the player exactly 10 meters above the ground several times (by simply editing the Transform inspector):

landing impact, velocity: 12,59808
landing impact, velocity: 2,384716
landing impact, velocity: 13,17809
landing impact, velocity: 3,737835
landing impact, velocity: 7,013631
landing impact, velocity: 4,580909
landing impact, velocity: 6,741642

By all accounts it shouldn't behave like this, since everything happens in FixedUpdate, It might be wrong numbers, but they should be consistently wrong, right? Not... this.
My code for calculating gravity is nothing complex either, it's basically velocity += Physics.gravity * Time.fixedDeltaTime

thick notch
#

CC should be Move'd exactly once per frame, aka in Update, not FixedUpdate

spring aspen
#

Ah. I thought that everything regarding moving characters and the like is physics, and physics should be in FixedUpdate.

thick notch
#

CC specifically is driven by the physics engine but isn't part of like.. the normal physics flow

spring aspen
thick notch
#

previousFrameVelocity there is framerate-dependant, you'd have to divide it by deltatime to get a per-second velocity, maybe try that?

#

also, what's the code you're using to log this (just as a sanity check)

spring aspen
# thick notch also, what's the code you're using to log this (just as a sanity check)

It's this one (I pass Y component of velocity into it)

        public void LandEvent(float impactVelocity)
        {            
            if (impactVelocity > 0)
            {
                return;
            }
            float absVelocity = impactVelocity.Abs();
            animatorControlComponent.TrySetTrigger("Landed");
            animatorControlComponent.TryResetTrigger("Fall");
            if (absVelocity > terminalVelocity)
            {
                SoundManager.PlayOneShot(crashSound, transform);
                float remainingVelocity = absVelocity - terminalVelocity;
                DevLog.Log("landing impact, velocity: " + absVelocity + ", remaining damage: " + remainingVelocity);
            }
            else
            {
                DevLog.Log("landing impact, velocity: " + absVelocity);
                SoundManager.PlayOneShot(landSound, transform);
            }
        }
thick notch
#

btw, interpolated strings would make this a bit easier to read, check them out

#

there's no like, technical difference, just makes a more pleasant time

thick notch
spring aspen
#

Yeah, apart of making the numbers smaller, it didn't had any effect from the looks of it.
I wonder if the editor lagging a bit might be the issue, though... All the time while I have my player selected, the FPS drops to ~30.

bright jolt
#

Maybe show the entire flow here, like when are you calling LandEvent and what is exactly passed into it?
if you're just passing in previousFrameVelocity.y then this is a variable you created and can debug further into why it's not lining up with what you expect it to be.
I wonder why you need this though since you are calculating gravity manually. Why do you need to read the difference in position if you're always in control of what the velocity should be

thick notch
#

have you tried checking throughout the fall if that's consistent? maybe it's inconsistent on the last frame due to hitting the ground