Skip to content

Instantly share code, notes, and snippets.

@pezcode
Created October 24, 2020 22:23
Show Gist options
  • Save pezcode/df7f8d8f73e76d8f37c5985f209ab475 to your computer and use it in GitHub Desktop.
Save pezcode/df7f8d8f73e76d8f37c5985f209ab475 to your computer and use it in GitHub Desktop.
Spherical camera mouse controller for Godot
extends Camera
# left mouse = rotate around pivot point
# right mouse = move pivot point left/right/up/down
# scroll wheel = move towards/away from pivot point
export var angular_speed := 1.0
export var movement_speed := 1.0
export var scroll_speed := 1.0
export var pivot := Vector3(0, 0, 0)
const UP := Vector3(0, 1, 0)
const FORWARD := Vector3(0, 0, -1)
func _ready():
look_at(pivot, UP)
func _unhandled_input(event):
var handled := false
if event is InputEventMouseMotion:
if Input.is_mouse_button_pressed(BUTTON_LEFT):
var delta := -Vector2(deg2rad(event.relative.y), deg2rad(event.relative.x)) * angular_speed
var up_angle := global_transform.basis.z.angle_to(UP)
delta.x = clamp(up_angle + delta.x, 0.1, PI - 0.1) - up_angle
global_translate(-pivot)
global_transform = global_transform \
.rotated(global_transform.basis.x, delta.x) \
.rotated(UP, delta.y)
global_translate(pivot)
handled = true
elif Input.is_mouse_button_pressed(BUTTON_RIGHT):
var delta = global_transform.basis * Vector3(-event.relative.x, event.relative.y, 0.0) * movement_speed
pivot += delta
global_translate(delta)
handled = true
elif event is InputEventMouseButton and event.pressed:
var delta := global_transform.origin.distance_to(pivot) * 0.1 * scroll_speed
if event.button_index == BUTTON_WHEEL_UP and event.pressed:
global_transform = global_transform.translated(FORWARD * delta)
handled = true
elif event.button_index == BUTTON_WHEEL_DOWN and event.pressed:
global_transform = global_transform.translated(-FORWARD * delta)
handled = true
if handled:
get_tree().set_input_as_handled()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment