Trying to create camera movement WSAD + RF (for vertical position), for which, the camera can move around the inside of a cylinder. The inner surface of the cylinder is 'down' and the centre axis of the cylinder is 'up'.

This is the CameraRig scene in the larger scene, which includes a cylinder mesh

Right now, I am creating a motion_input_vector, normalizing it. multiplying it by a 'speed' var, and translating the CameraRig.

Then I try to re-orient the CameraRig to point to the centre axis of the cylinder. To do this I am trying to calculate a normailized vector from CameraRig Origin to the corrisponding offset point of the cylinder centre axis. Then using cross product to recalculate the Rig's Basis axes, and re-applying all that to the Rig's Transform. I haven't yet added anything to counteract the vertical sliding I extect from moving the Rig first in its horizontal plane only, then reorienting it.

but I am getting unexpectedly large translations visually, but very little shows up when I print the transform values. it's just jumping about crazily.

If anyone can show me what I am doing wrong I will sell a kidney for you, maybe.

extends Spatial

export var camera_speed = 1.0

func _ready():
	pass # Replace with function body.

func _process(delta):
	var motion_input_vector = Vector3(0,0,0)
	var is_action_pressed = false
	
	# Take Movement Input
	# Build Input Vector
	if Input.is_action_pressed("ui_left"):
		motion_input_vector.x = -1
		is_action_pressed = true
		pass
	elif Input.is_action_pressed("ui_right"):
		motion_input_vector.x = 1
		is_action_pressed = true
		pass
	
	if Input.is_action_pressed("ui_forward"):
		motion_input_vector.z = -1
		is_action_pressed = true
		pass
	elif Input.is_action_pressed("ui_backward"):
		motion_input_vector.z = 1
		is_action_pressed = true
		pass
	
	if Input.is_action_pressed("ui_up"):
		motion_input_vector.y = 1
		is_action_pressed = true
		pass
	elif Input.is_action_pressed("ui_down"):
		motion_input_vector.y = -1
		is_action_pressed = true
		pass
	
	if is_action_pressed:
		motion_input_vector = motion_input_vector.normalized()
		motion_input_vector = motion_input_vector * camera_speed
		translate(motion_input_vector)
		
		# Re-Orient Rig-Transform so its Y always points to cyclinder-centre
			# get position of centre offset by camera z
		var offset_cylinder_centre = Vector3( 0, 0, transform.origin.z)
			# get direciton to centre from camera position
		var direction_to_centre = offset_cylinder_centre - transform.origin
		var new_y = direction_to_centre.normalized()
			# calculate new X and Z axis
		var new_x = new_y.cross(transform.basis.z)
		var new_z = new_y.cross(new_x)
			# create new transform
		var new_transform = Transform(new_x, new_y, new_z, transform.origin)
		new_transform = new_transform.orthonormalized()
			# apply that direction to camera UP
		transform = new_transform
		pass
	
	is_action_pressed = false
	pass
15 days later

Hello. I think the key to making this happen is changing your node order around a bit and using parenting to your advantage. When you parent your camera rig to the center of the cylinder and have the camera rotate around it, the calculations become much more simple.... If I misinterpreted what you needed or have questions, let me know and I'll try to help. Good luck, keep at it! _

Here is the script on the Camera_Rig node...

extends Spatial

onready var Cam = self.get_node("Camera")

export(float) var rotation_speed = 0.5
export(float) var translation_speed = 0.5

func _process(delta):
	
	if Input.is_key_pressed(KEY_W):
		self.Cam.translation += -self.Cam.transform.basis.z * self.translation_speed * delta
	if Input.is_key_pressed(KEY_S):
		self.Cam.translation += self.Cam.transform.basis.z * self.translation_speed * delta
	if Input.is_key_pressed(KEY_D):
		self.rotate_y(self.rotation_speed * delta)
	if Input.is_key_pressed(KEY_A):
		self.rotate_y(-self.rotation_speed * delta)
	if Input.is_key_pressed(KEY_R):
		self.translation.y += self.translation_speed * delta 
	if Input.is_key_pressed(KEY_F):
		self.translation.y += -self.translation_speed * delta

Oh, and to answer your question about the large translations. You should multiply any translations you make by the delta value because this "process" function is happening 60 times per second. So if your camera_speed is 1.0 and you hold down the key for 1 second, it will move 60 units, which is a lot. But if you multiply the camera_speed by the delta parameter that comes with the "process" function, the camera_speed will be decreased to the exact amount it needs every frame such that when you press the button for 1 second, it will move 1 unit. Hope that was clear. It's not always the easiest thing to wrap one's head around and has been the cause of many of my headaches. lol But, you can see an example of it working in the script above. Have fun!

3 years later