Godot Version
4.7.2
Question
Right now the operations are separate, the Submersible turns left or right or goes forwards and backwards.
I cannot figure out how to make the z axis movement coincide with the rotation on the y axis.
Currently it spins any direction, and then goes forwards and backwards on the global z axis instead of following its front end.
Maybe I am missing something obvious, I apologize if so.
extends CharacterBody3D
@onready var submersible_scout_drone: CharacterBody3D = $"."
@export var maxspeed = 2.5
@export var turnspeed = 0.005
func conn_PS(delta): #Turns Port Side (y) and Starboard Side (-y)
var Tdirection = Vector3()
Tdirection.y = Input.get_axis("Port", "Starboard")
var SSD = submersible_scout_drone
SSD.rotation += Tdirection * turnspeed
func conn_BS(delta): #Moves towards the Bow (-z) and the Stern (z)
var direction = Vector3()
direction.z = Input.get_axis("Bow", "Stern")
var target = direction * maxspeed
var acceleration = 2
var speed = velocity
speed = speed.lerp(target, acceleration * delta)
velocity = speed
print ("Position", submersible_scout_drone.position)
print ("Rotation", submersible_scout_drone.rotation)
func _physics_process(delta: float) -> void:
conn_BS(delta)
conn_PS(delta)
move_and_slide()
You maybe better served using something like this. Basically you need to do the motion and direction as a single shot.
extends CharacterBody3D
@export var speed: float = 5.0
@export var acceleration: float = 4.0
func _ready() -> void:
# Treat all surfaces as walls so sliding doesn't stop or slow down like a platformer
motion_mode = MOTION_MODE_FLOATING
func _physics_process(delta: float) -> void:
# Get movement inputs (-1 to 1)
var input_dir := Vector3.ZERO
# Forward / Backward (W/S or Up/Down arrows)
input_dir.z = Input.get_axis("ui_down", "ui_up")
# Left / Right (A/D or Left/Right arrows)
input_dir.x = Input.get_axis("ui_left", "ui_right")
# Up / Down depth movement (QE keys or custom actions)
if Input.is_action_pressed("move_up"): # define in Project Settings
input_dir.y += 1.0
if Input.is_action_pressed("move_down"): # define in Project Settings
input_dir.y -= 1.0
# Transform input based on the submersible's current rotation/orientation
var direction := (transform.basis * input_dir).normalized()
if direction:
velocity.x = move_toward(velocity.x, direction.x * speed, acceleration * delta)
velocity.y = move_toward(velocity.y, direction.y * speed, acceleration * delta)
velocity.z = move_toward(velocity.z, direction.z * speed, acceleration * delta)
else:
velocity.x = move_toward(velocity.x, 0, acceleration * delta)
velocity.y = move_toward(velocity.y, 0, acceleration * delta)
velocity.z = move_toward(velocity.z, 0, acceleration * delta)
move_and_slide()
This is great, but unfortunately this makes side to side motion like a side scroller, instead of panning side to side like submarines do.
I’m sure I’ll figure something out, thank you.