Godot Version
v4.2.2.stable.official [15073afe3]
Question
Hello. I am trying to implement a feature in which the player can switch between two CharacterBody3D’s by pressing a button to switch one way and holding the button for a certain amount of time to switch back. The problem is, that the system works, but the timer doesn’t reset if the button is let go. In practice, the player can just spam press E (or “interact”) to switch back. I don’t want this to be the case. Any help is appreciated. I’ll answer any questions as needed. The feature that isn’t working is the line “await get_tree().create_timer(1).timeout”
extends CharacterBody3D
var speed
var execute_this_code: bool = false
const WALK_SPEED = 5.0
const SPRINT_SPEED = 8.0
const JUMP_VELOCITY = 4.5
const SENSITIVITY = 0.003
#bob variables
const BOB_FREQ = 2.0
const BOB_AMP = 0.08
var t_bob = 0.0
@onready var mech = $"."
@onready var player = $"../Player"
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
func _process(delta):
if Input.is_action_just_pressed("interact"):
exit()
func _unhandled_input(event):
if execute_this_code:
if event is InputEventMouseMotion:
mech.rotate_y(-event.relative.x * SENSITIVITY)
mech.rotation.x = clamp(mech.rotation.x, deg_to_rad(0), deg_to_rad(0))
func _physics_process(delta):
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
if not is_on_floor():
velocity.y -= gravity * delta
if Input.is_action_pressed("sprint"):
speed = SPRINT_SPEED
else:
speed = WALK_SPEED
if execute_this_code:
var input_dir = Input.get_vector("left", "right", "forward", "backward")
var direction = (mech.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if is_on_floor():
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = lerp(velocity.x, direction.x * speed, delta * 7.0)
velocity.z = lerp(velocity.z, direction.z * speed, delta * 7.0)
else:
velocity.x = lerp(velocity.x, direction.x * speed, delta * 3.0)
velocity.z = lerp(velocity.z, direction.z * speed, delta * 3.0)
#Head bob
t_bob += delta * velocity.length() * float(is_on_floor())
$Camera3D.transform.origin = _headbob(t_bob)
move_and_slide()
func _headbob(time) -> Vector3:
var pos = Vector3.ZERO
pos.y = sin(time * BOB_FREQ) * BOB_AMP
pos.x = cos(time * BOB_FREQ / 2) * BOB_AMP
return pos
func enter(body):
execute_this_code = true
player.execute_this_code = false
$"../Player/Head/Camera3D/InteractRay".enabled = false
$"../Player/Head/Camera3D".current = false
$Camera3D.make_current()
func exit():
if execute_this_code:
if !Input.is_action_pressed("interact"):
return
await get_tree().create_timer(1).timeout
if !Input.is_action_pressed("interact"):
return
execute_this_code = false
player.execute_this_code = true
$"../Player/Head/Camera3D/InteractRay".enabled = true
$Camera3D.current = false
$"../Player/Head/Camera3D".make_current()
print("good")
func _on_seat_interacted(body):
pass