Difficulty calculating simple inertia

Godot Version

4.3

Question

What is a good way to calculate a simple form of intertia?

I just want a CharacterBody3D to continue moving in the direction it is facing even if the player has stopped pressing forward or back.

I’ve tried calculating it in _physics_process() and in get_input(), but my implementation didn’t work.

It’s based off of KenneyNL’s third person controller starter, and here is the CharacterBody3D without any inertia calculations:

extends CharacterBody3D

var move_spd := 10.0
var turn_spd := 3.0
var jump_spd := 7.0

var gravity := 0.0
var mass := 100.0

var move_dir := 0.0
var move_vel := Vector3.ZERO

func _ready() -> void:
	pass

func _physics_process(delta: float) -> void:
	get_input(delta)
	apply_gravity(delta)
	
	var dir := 0.0
	var vel := Vector3.ZERO
	
	dir = lerp_angle(rotation.y, move_dir, delta * 10)
	vel = lerp(velocity, move_vel, delta * 10)
	vel.y = gravity
	
	rotation.y = dir
	velocity = vel
	
	apply_friction(delta, 4.0)
	move_and_slide()
	
	if position.y < -10:
		get_tree().reload_current_scene()

func get_input(delta: float) -> void:
	var input := Vector3(
		Input.get_axis("left", "right"),
		0,
		Input.get_axis("forward", "back")
	)
	
	move_dir -= input.x * turn_spd * delta
	move_vel += input.z * move_spd * transform.basis.z * delta
	
	if Input.is_action_just_pressed("jump"):
		if is_on_floor():
			gravity = jump_spd
	
	if Input.is_action_just_pressed("escape"):
		get_tree().quit()
	if Input.is_action_just_pressed("tab"):
		get_tree().reload_current_scene()
	#if Input.is_action_just_pressed("tilde"):
	#	# debug menu
	#	pass

func apply_gravity(delta: float, impulse: float = 10.0, factor: float = 2.0) -> void:
	gravity -= impulse * delta * factor
	
	if gravity < 0 and is_on_floor():
		gravity = 0

func apply_friction(delta: float, factor: float = 1.0) -> void:
	move_vel = lerp(move_vel, Vector3.ZERO, delta * factor)

I solved the issue; transform was being calculated in the wrong area, and I could have used an input.get_vector() instead of a vec3

extends CharacterBody3D

var move_spd := 10.0
var turn_spd := 3.0
var jump_spd := 7.0

var gravity := 0.0
var mass := 100.0

var move_dir := 0.0
var move_vel := Vector3.ZERO

func _ready() -> void:
	pass

func _physics_process(delta: float) -> void:
	get_input(delta)
	apply_gravity(delta)
	
	rotation.y = move_dir
	**velocity = move_vel * transform.basis.inverse()**
	
	apply_friction(delta, 4.0)
	move_and_slide()
	
	if position.y < -10:
		get_tree().reload_current_scene()

func get_input(delta: float) -> void:
	**var input := Input.get_vector("left", "right", "forward", "back")**
	
	move_dir -= input.x * turn_spd * delta
	**move_vel += input.z * move_spd * delta**
	
	if Input.is_action_just_pressed("jump"):
		if is_on_floor():
			gravity = jump_spd
	
	if Input.is_action_just_pressed("escape"):
		get_tree().quit()
	if Input.is_action_just_pressed("tab"):
		get_tree().reload_current_scene()

func apply_gravity(delta: float, impulse: float = 10.0, factor: float = 2.0) -> void:
	gravity -= impulse * delta * factor
	
	if gravity < 0 and is_on_floor():
		gravity = 0

func apply_friction(delta: float, factor: float = 1.0) -> void:
	move_vel = lerp(move_vel, Vector3.ZERO, delta * factor)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.