Skip to content

Instantly share code, notes, and snippets.

@AndreaCatania
Last active January 7, 2022 10:55
Show Gist options
  • Save AndreaCatania/316fc412a7b478ca5226b5c17d963737 to your computer and use it in GitHub Desktop.
Save AndreaCatania/316fc412a7b478ca5226b5c17d963737 to your computer and use it in GitHub Desktop.
Godot Fly camera utility - Single file
extends Camera3D
class_name FlyCamera
## Simple Fly Camera for Godot Engine 3.x / 4.x.
## This Fly camera can be moved using the mouse and keyboard "WASD".
## You can toggle this camera activation by pressing the TAB key.
## The idea is to put this camera as autoload.
## It's possible to customize it by changing: The mouse `sensibility` and camera `speed`.
##
## If you want to contribute, please leave a comment, I'll update the code.
##
## License: MIT.
##
## ~~~~~~~~~~~~~~~~
## Make this discoverable by people:
## How to create a fly camera in Godot?
## Godot fly camera.
## Fly camera tutorial.
## Fly camera utility.
## ~~~~~~~~~~~~~~~~
##
# ------------------------------------------------------------------------ Const
const speed = 0.1
const sensitivity = 0.001
# ----------------------------------------------------------------------- Global
var active := false
var motion: Vector3
var view_motion: Vector2
var gimbal_base: Transform
var gimbal_pitch: Transform
var gimbal_yaw: Transform
# ----------------------------------------------------------------------- Public
func is_active() -> bool:
""" Return true when the fly camera is active. You can toggle the fly
camera using the TAB keyboard. """
return active
# ----------------------------------------------------------------- Notification
func _ready():
gimbal_base.origin = global_transform.origin
# Unparent
set_as_top_level(true)
update_activation()
func _input(event):
if event is InputEventMouseMotion:
view_motion += event.relative
get_viewport().set_input_as_handled()
elif event is InputEventKey:
if event.keycode == KEY_TAB:
if event.pressed:
# Each click toggle.
active = active == false
update_activation()
return
if active == false:
return
var value: float = 0
if event.pressed:
value = 1
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if event.keycode == KEY_W:
motion.z = value * -1.0
elif event.keycode == KEY_S:
motion.z = value
elif event.keycode == KEY_A:
motion.x = value * -1.0
elif event.keycode == KEY_D:
motion.x = value
else:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
get_viewport().set_input_as_handled()
func _process(delta):
gimbal_base *= Transform(Basis(), global_transform.basis * (motion * speed))
gimbal_yaw = gimbal_yaw.rotated(Vector3(0,1,0), view_motion.x * sensitivity * -1.0)
gimbal_pitch = gimbal_pitch.rotated(Vector3(1,0,0), view_motion.y * sensitivity * -1.0)
view_motion = Vector2()
global_transform = gimbal_base * (gimbal_yaw * gimbal_pitch)
# ---------------------------------------------------------------------- Private
func update_activation():
set_process(active)
current = active
if active == false:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment