Skip to content

Instantly share code, notes, and snippets.

@Calinou
Last active July 12, 2019 05:27
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Calinou/820ca6211eef32f531d26e89c4262de9 to your computer and use it in GitHub Desktop.
Save Calinou/820ca6211eef32f531d26e89c4262de9 to your computer and use it in GitHub Desktop.
Freelook camera script from my Sponza demo
# Copyright © 2017 Hugo Locurcio and contributors - MIT license
# See LICENSE.md included in the source distribution for more information.
extends Camera
const MOVE_SPEED = 0.5
const MOUSE_SENSITIVITY = 0.002
onready var speed = 1
onready var velocity = Vector3()
onready var initial_rotation = PI/2
func _enter_tree():
# Capture the mouse (can be toggled by pressing F10)
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
# Horizontal mouse look
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotation.y -= event.relative.x*MOUSE_SENSITIVITY
# Vertical mouse look, clamped to -90..90 degrees
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotation.x = clamp(rotation.x - event.relative.y*MOUSE_SENSITIVITY, deg2rad(-90), deg2rad(90))
# Toggle HUD
if event.is_action_pressed("toggle_hud"):
$"../FPSCounter".visible = !$"../FPSCounter".visible
# Toggle mouse capture
if event.is_action_pressed("toggle_mouse_capture"):
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _physics_process(delta):
# Speed modifier
if Input.is_action_pressed("move_speed"):
speed = 2
else:
speed = 1
# Movement
if Input.is_action_pressed("move_forward"):
velocity.x -= MOVE_SPEED*speed*delta
if Input.is_action_pressed("move_backward"):
velocity.x += MOVE_SPEED*speed*delta
if Input.is_action_pressed("move_left"):
velocity.z += MOVE_SPEED*speed*delta
if Input.is_action_pressed("move_right"):
velocity.z -= MOVE_SPEED*speed*delta
if Input.is_action_pressed("move_up"):
velocity.y += MOVE_SPEED*speed*delta
if Input.is_action_pressed("move_down"):
velocity.y -= MOVE_SPEED*speed*delta
# Friction
velocity *= 0.875
# Apply velocity
translation += velocity \
.rotated(Vector3(0, 1, 0), rotation.y - initial_rotation) \
.rotated(Vector3(1, 0, 0), cos(rotation.y)*rotation.x) \
.rotated(Vector3(0, 0, 1), -sin(rotation.y)*rotation.x)
func _exit_tree():
# Restore the mouse cursor upon quitting
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
@vddCore
Copy link

vddCore commented Jun 3, 2018

Translated to C# API

using Godot;
using System;

public class FreeLook : Camera
{
    public float MouseSensitivity = 0.002f;
    public float MoveSpeed = 0.5f;
    
    public float Speed = 5;
    public Vector3 Velocity = new Vector3(0, 0, 0);
    public float InitialRotation = (float)Math.PI / 2f;
    
    public override void _EnterTree()
    {
        Input.SetMouseMode(Input.MouseMode.Captured);
    }
    
    public override void _Input(InputEvent ev)
    {
        if(ev is InputEventMouseMotion && Input.GetMouseMode() == Input.MouseMode.Captured)
        {
            var newY = Rotation.y - (ev as InputEventMouseMotion).Relative.x * MouseSensitivity;
            var newZ = Mathf.Clamp(Rotation.x - (ev as InputEventMouseMotion).Relative.y  * MouseSensitivity, ((float)Math.PI / 180) * -90, ((float)Math.PI / 180) * 90);
            Rotation = new Vector3(newZ, newY, Rotation.z);
        }
        
        if(Input.IsActionPressed("ToggleMouseCapture"))
        {
            if(Input.GetMouseMode() == Input.MouseMode.Captured)
                Input.SetMouseMode(Input.MouseMode.Visible);
            else
                Input.SetMouseMode(Input.MouseMode.Captured);
        }
    }
    
    public override void _PhysicsProcess(float delta)
    {
        if(Input.IsActionPressed("BoostFreelook"))
            Speed = 10;
        else
            Speed = 5;
        
        var newX = 0f;
        var newY = 0f;
        var newZ = 0f;
        if(Input.IsActionPressed("MoveFreelookForward"))
            newX = -(MoveSpeed * Speed * delta);
        
        if(Input.IsActionPressed("MoveFreelookBackward"))
            newX = MoveSpeed * Speed * delta;
        
        if(Input.IsActionPressed("MoveFreelookLeft"))
            newZ = MoveSpeed * Speed * delta;
            
        if(Input.IsActionPressed("MoveFreelookRight"))
            newZ = -(MoveSpeed * Speed * delta);
            
        if(Input.IsActionPressed("MoveFreelookUpwards"))
            newY = MoveSpeed * Speed * delta;
            
        if(Input.IsActionPressed("MoveFreelookDownwards"))
            newY = -(MoveSpeed * Speed * delta);
            
        Velocity = new Vector3(newX * 0.875f, newY * 0.875f, newZ * 0.875f);
        
        Translation += Velocity
        .Rotated(new Vector3(0, 1, 0), Rotation.y - InitialRotation)
        .Rotated(new Vector3(1, 0, 0), (float)Math.Cos(Rotation.y) * Rotation.x)
        .Rotated(new Vector3(0, 0, 1), (float)-Math.Sin(Rotation.y) * Rotation.x);
    }

    public override void _ExitTree()
    {
        Input.SetMouseMode(Input.MouseMode.Visible);
    }
}

@TheDuriel
Copy link

TheDuriel commented Jul 12, 2019

# Copyright © 2017 Hugo Locurcio and contributors - MIT license
# Copyright © 2019 Manuel 'TheDuriel' Fischer - MIT license
extends Camera
class_name DebugCamera

const MOVE_SPEED: float = 1.0
const MOUSE_SENSITIVITY: float = 0.002

onready var speed: int = 1
onready var velocity: Vector3 = Vector3()
onready var initial_rotation: float = TAU / 4


func _ready() -> void:
	# Capture the mouse (can be toggled by pressing 1)
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)


func _input(event) -> void:
	# Horizontal mouse look
	if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
		rotation.y -= event.relative.x*MOUSE_SENSITIVITY
	
	# Vertical mouse look, clamped to -90..90 degrees
	if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
		rotation.x = clamp(rotation.x - event.relative.y*MOUSE_SENSITIVITY, deg2rad(-90), deg2rad(90))
	
	# Toggle mouse capture
	if event is InputEventKey and event.scancode == KEY_1 and not event.is_echo():
		if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
			Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
		else:
			Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)


func _physics_process(delta: float) -> void:
	# Speed modifier
	if Input.is_key_pressed(KEY_SHIFT):
		speed = 2
	else:
		speed = 1
	
	# Movement
	if Input.is_key_pressed(KEY_W):
		velocity.x -= MOVE_SPEED*speed*delta
	if Input.is_key_pressed(KEY_S):
		velocity.x += MOVE_SPEED*speed*delta
	if Input.is_key_pressed(KEY_A):
		velocity.z += MOVE_SPEED*speed*delta
	if Input.is_key_pressed(KEY_D):
		velocity.z -= MOVE_SPEED*speed*delta
	
	
	if Input.is_key_pressed(KEY_E):
		velocity.y += MOVE_SPEED*speed*delta
	if Input.is_key_pressed(KEY_Q):
		velocity.y -= MOVE_SPEED*speed*delta
	
	# Friction
	velocity *= 0.875
	
	# Apply velocity
	translation += velocity \
	.rotated(Vector3(0, 1, 0), rotation.y - initial_rotation) \
	.rotated(Vector3(1, 0, 0), cos(rotation.y)*rotation.x) \
	.rotated(Vector3(0, 0, 1), -sin(rotation.y)*rotation.x)


func _exit_tree() -> void:
	# Restore the mouse cursor upon quitting
	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