Skip to content

Instantly share code, notes, and snippets.

@FreyaHolmer
Last active April 15, 2024 04:49
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"
}
}
@MentalGear
Copy link

Thanks, this helped me figure out my flight controller without tilting the z axis (the trick is that rotate of the x axis has to be on space.world, but on y axis on the space.self) !

@GadirajuSanjayvarma
Copy link

Thank you.It is great

@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 :)

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