Thank you for the response @tayacan!
No, the player does not need to be able to move while holding down one of these buttons. Could you provide an example or explanation as to how you achieve your first method (lock the player’s movement + rotation when they start pressing the button, make the player a child of the platform, and then reverse all of that the moment they let go) through gdscript? Sorry about the video, I’ll add my code below:
FPS Controller:
extends CharacterBody3D
var speed
var vel = Vector3()
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
#fov variables
const BASE_FOV = 75.0
const FOV_CHANGE = 1.5
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
@onready var head = $Head
@onready var camera = $Head/Camera3D
@onready var mech = $".."
@onready var body = $"."
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _unhandled_input(event):
if event is InputEventMouseMotion:
head.rotate_y(-event.relative.x * SENSITIVITY)
camera.rotate_x(-event.relative.y * SENSITIVITY)
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(60))
func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y -= gravity * delta
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
#Handle sprint.
if Input.is_action_pressed("sprint"):
speed = SPRINT_SPEED
else:
speed = WALK_SPEED
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var input_dir = Input.get_vector("left", "right", "forward", "backward")
var direction = (head.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())
camera.transform.origin = _headbob(t_bob)
#FOV
var velocity_clamped = clamp(velocity.length(), 0.5, SPRINT_SPEED * 2)
var target_fov = BASE_FOV + FOV_CHANGE * velocity_clamped
camera.fov = lerp(camera.fov, target_fov, delta * 8.0)
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 new_parent():
reparent($"../MechtestPlatform")
Button
extends CollisionObject3D
class_name Interactable
signal interacted(body)
signal released(body)
@export var prompt_message = "Interact"
func interact(body):
interacted.emit(body)
func release(body):
released.emit(body)
Interact Raycast
extends RayCast3D
@onready var prompt = $Prompt
@onready var camera = $"../.."
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
prompt.text = ""
if is_colliding():
var collider = get_collider()
if collider is Interactable:
prompt.text = collider.prompt_message
if Input.is_action_pressed("interact"):
collider.interact(owner)
#camera.look_at(collider.global_position, Vector3.UP)
#if Input.is_action_just_released("interact"):
else:
collider.release(owner)
Platform
extends Node3D
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
pass
func right(body):
rotate_y(.01)
get_node(".")
func right_stop(body):
rotate_y(0)
func _on_button_interacted(_body):
pass # Replace with function body.
func _on_button_released(_body):
pass # Replace with function body.