Skip to content

Instantly share code, notes, and snippets.

@FreyaHolmer
Last active November 6, 2024 13:53
Show Gist options
  • Save FreyaHolmer/650ecd551562352120445513efa1d952 to your computer and use it in GitHub Desktop.
Save FreyaHolmer/650ecd551562352120445513efa1d952 to your computer and use it in GitHub Desktop.
A camera controller for easily flying around a scene in Unity smoothly. WASD for lateral movement, Space & Ctrl for vertical movement, Shift to move faster. Add this script to an existing camera, or an empty game object, hit play, and you're ready to go~
using UnityEngine;
[RequireComponent( typeof(Camera) )]
public class FlyCamera : MonoBehaviour {
public float acceleration = 50; // how fast you accelerate
public float accSprintMultiplier = 4; // how much faster you go when "sprinting"
public float lookSensitivity = 1; // mouse look sensitivity
public float dampingCoefficient = 5; // how quickly you break to a halt after you stop your input
public bool focusOnEnable = true; // whether or not to focus and lock cursor immediately on enable
Vector3 velocity; // current velocity
static bool Focused {
get => Cursor.lockState == CursorLockMode.Locked;
set {
Cursor.lockState = value ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = value == false;
}
}
void OnEnable() {
if( focusOnEnable ) Focused = true;
}
void OnDisable() => Focused = false;
void Update() {
// Input
if( Focused )
UpdateInput();
else if( Input.GetMouseButtonDown( 0 ) )
Focused = true;
// Physics
velocity = Vector3.Lerp( velocity, Vector3.zero, dampingCoefficient * Time.deltaTime );
transform.position += velocity * Time.deltaTime;
}
void UpdateInput() {
// Position
velocity += GetAccelerationVector() * Time.deltaTime;
// Rotation
Vector2 mouseDelta = lookSensitivity * new Vector2( Input.GetAxis( "Mouse X" ), -Input.GetAxis( "Mouse Y" ) );
Quaternion rotation = transform.rotation;
Quaternion horiz = Quaternion.AngleAxis( mouseDelta.x, Vector3.up );
Quaternion vert = Quaternion.AngleAxis( mouseDelta.y, Vector3.right );
transform.rotation = horiz * rotation * vert;
// Leave cursor lock
if( Input.GetKeyDown( KeyCode.Escape ) )
Focused = false;
}
Vector3 GetAccelerationVector() {
Vector3 moveInput = default;
void AddMovement( KeyCode key, Vector3 dir ) {
if( Input.GetKey( key ) )
moveInput += dir;
}
AddMovement( KeyCode.W, Vector3.forward );
AddMovement( KeyCode.S, Vector3.back );
AddMovement( KeyCode.D, Vector3.right );
AddMovement( KeyCode.A, Vector3.left );
AddMovement( KeyCode.Space, Vector3.up );
AddMovement( KeyCode.LeftControl, Vector3.down );
Vector3 direction = transform.TransformVector( moveInput.normalized );
if( Input.GetKey( KeyCode.LeftShift ) )
return direction * ( acceleration * accSprintMultiplier ); // "sprinting"
return direction * acceleration; // "walking"
}
}
@VojtaStruhar
Copy link

VojtaStruhar commented Aug 29, 2022

For "Minecraft-like" up and down (global up-down), wrap the vectors on lines 67-68 in transform.InverseTransformDirection. I don't know why, but I'm really used to those controls :)

So that would be

AddMovement( KeyCode.Space, transform.InverseTransformDirection(Vector3.up) );
AddMovement( KeyCode.LeftControl, transform.InverseTransformDirection(Vector3.down) );

Awesome controller, thank you so much! ❤️

@ndsl95
Copy link

ndsl95 commented May 8, 2023

thank you.It work great.

@OFGONEN
Copy link

OFGONEN commented Aug 16, 2023

@VojtaStruhar You don't need to invoke InverseTransformDirection, transform.up is the vector you need.
AddMovement( KeyCode.Space, transform.up );

@Lokecrafter
Copy link

Nice script. Just what I needed for viewing my math visualization :)

@giande2000
Copy link

Awesome to test scenes, works perfectly. Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment