Godot Version
v. 4.0.3
Question
So I’m learning to program different types of cameras for 3D games, but I’m having trouble. Many games nowadays use an over-the-shoulder camera where the mouse input controls the direction the camera is facing, not the camera itself. I’ve already been able to program the over-the-shoulder kind of camera, but I’m looking to replicate early 3D camera physics - where going forward means moving away relative to the camera. Whereas I originally had an input function to have the camera dictate the rotation of the model in real time, I would like the camera to rotate around the model and only have that rotation affect it when a directional action is pressed, and I have managed to achieve this using the get_global_transform().basis.z. The problem is that the rotation completely skews the model and I have no idea how to fix it. When facing the left and right (-X and X), the model becomes incredibly thin, and looks unnatural at any rotation angle. How do I perform these rotations without warping the model?
extends RigidBody3D
var mouse_sensitivity := 0.001
var twist_input := 0.0
var pitch_input := 0.0
@onready var animation_player = $“medgestandingriggedmapping3+animation2/AnimationPlayer”
@onready var twist_pivot := $TwistPivot
@onready var pitch_pivot := $TwistPivot/PitchPivot
func _ready() → void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
animation_player.play(“Idle”)
func _process(delta: float) → void:
var input := Vector3.ZERO
var vector3_f = $TwistPivot/PitchPivot/Camera3D.get_global_transform().basis.z
input.x = Input.get_axis(“move_left”, “move_right”)
input.z = Input.get_axis(“move_forward”,“move_back”)
if Input.is_action_just_pressed("move_forward"):
#This line here vv causes models to warp
$“medgestandingriggedmapping3+animation2”.basis.z = -vector3_f
if animation_player.current_animation != “Running”:
animation_player.play(“Running”)
if Input.is_action_just_released("move_forward"):
if animation_player.current_animation == "Running":
animation_player.play("Idle")
apply_central_force(twist_pivot.basis * input * 1200.0 * delta)
if Input.is_action_just_pressed("ui_cancel"):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
if Input.is_action_just_pressed("Click"):
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
twist_pivot.rotate_y(twist_input)
pitch_pivot.rotate_x(pitch_input)
pitch_pivot.rotation.x = clamp(pitch_pivot.rotation.x,
deg_to_rad(-30),
deg_to_rad(30)
)
twist_input = 0.0
pitch_input = 0.0
func _unhandled_input(event: InputEvent) → void:
if event is InputEventMouseMotion:
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
twist_input = - event.relative.x * mouse_sensitivity
pitch_input = - event.relative.y * mouse_sensitivity