Skip to content

Instantly share code, notes, and snippets.

@gunderson
Last active January 15, 2024 16:31
Star You must be signed in to star a gist
Save gunderson/d7f096bd07874f31671306318019d996 to your computer and use it in GitHub Desktop.
Unity Script to give camera WASD + mouse control
using UnityEngine;
using System.Collections;
public class FlyCamera : MonoBehaviour {
/*
Writen by Windexglow 11-13-10. Use it, edit it, steal it I don't care.
Converted to C# 27-02-13 - no credit wanted.
Simple flycam I made, since I couldn't find any others made public.
Made simple to use (drag and drop, done) for regular keyboard layout
wasd : basic movement
shift : Makes camera accelerate
space : Moves camera on X and Z axis only. So camera doesn't gain any height*/
float mainSpeed = 100.0f; //regular speed
float shiftAdd = 250.0f; //multiplied by how long shift is held. Basically running
float maxShift = 1000.0f; //Maximum speed when holdin gshift
float camSens = 0.25f; //How sensitive it with mouse
private Vector3 lastMouse = new Vector3(255, 255, 255); //kind of in the middle of the screen, rather than at the top (play)
private float totalRun= 1.0f;
void Update () {
lastMouse = Input.mousePosition - lastMouse ;
lastMouse = new Vector3(-lastMouse.y * camSens, lastMouse.x * camSens, 0 );
lastMouse = new Vector3(transform.eulerAngles.x + lastMouse.x , transform.eulerAngles.y + lastMouse.y, 0);
transform.eulerAngles = lastMouse;
lastMouse = Input.mousePosition;
//Mouse camera angle done.
//Keyboard commands
float f = 0.0f;
Vector3 p = GetBaseInput();
if (p.sqrMagnitude > 0){ // only move while a direction key is pressed
if (Input.GetKey (KeyCode.LeftShift)){
totalRun += Time.deltaTime;
p = p * totalRun * shiftAdd;
p.x = Mathf.Clamp(p.x, -maxShift, maxShift);
p.y = Mathf.Clamp(p.y, -maxShift, maxShift);
p.z = Mathf.Clamp(p.z, -maxShift, maxShift);
} else {
totalRun = Mathf.Clamp(totalRun * 0.5f, 1f, 1000f);
p = p * mainSpeed;
}
p = p * Time.deltaTime;
Vector3 newPosition = transform.position;
if (Input.GetKey(KeyCode.Space)){ //If player wants to move on X and Z axis only
transform.Translate(p);
newPosition.x = transform.position.x;
newPosition.z = transform.position.z;
transform.position = newPosition;
} else {
transform.Translate(p);
}
}
}
private Vector3 GetBaseInput() { //returns the basic values, if it's 0 than it's not active.
Vector3 p_Velocity = new Vector3();
if (Input.GetKey (KeyCode.W)){
p_Velocity += new Vector3(0, 0 , 1);
}
if (Input.GetKey (KeyCode.S)){
p_Velocity += new Vector3(0, 0, -1);
}
if (Input.GetKey (KeyCode.A)){
p_Velocity += new Vector3(-1, 0, 0);
}
if (Input.GetKey (KeyCode.D)){
p_Velocity += new Vector3(1, 0, 0);
}
return p_Velocity;
}
}
@illegitimate-egg
Copy link

The associated script can not be loaded. Please fix any complie errors and assign a valid script.

You need to make sure that your script name and monobehaviour name are the same

@Wiltor790
Copy link

i dont know if i am the only one but it simply doesnt work. i cheked unity official tutorials and copied the code they wrote, but didnt work. please someone help me. PS: using 2020.2.6f1

@Wiltor790
Copy link

i dont know if i am the only one but it simply doesnt work. i cheked unity official tutorials and copied the code they wrote, but didnt work. please someone help me. PS: using 2020.2.6f1

@illegitimate-egg
Copy link

What error are you getting?

@chaifix
Copy link

chaifix commented Apr 1, 2021

Very nice.

@Masterxilo
Copy link

Thanks for this. That should be a built-in feature...

@AlexE20102
Copy link

How do I make it so you don't have to right-click to move around?

@docboymex
Copy link

comment in Update this line

if (Input.GetMouseButton(0))

Copy link

ghost commented May 3, 2021

Nice

@gunderson
Copy link
Author

I made a change so that you aren't constantly moving but only move when pressing a wasd key.

@Picpiw
Copy link

Picpiw commented May 26, 2021

thanks pro

@jhchnc
Copy link

jhchnc commented Jul 12, 2021

This will restrain mouse movements to the middle button. (Useful for games where selecting things with the mouse buttons is required.)

        if (Input.GetMouseButton(2)) {
            lastMouse = Input.mousePosition - lastMouse ;
            lastMouse = new Vector3(-lastMouse.y * camSens, lastMouse.x * camSens, 0 );
            lastMouse = new Vector3(transform.eulerAngles.x + lastMouse.x , transform.eulerAngles.y + lastMouse.y, 0);
            transform.eulerAngles = lastMouse;
            //Mouse  camera angle done.  
        }
        lastMouse =  Input.mousePosition;

@gunderson
Copy link
Author

Thanks!

@irvwais
Copy link

irvwais commented Jul 21, 2021

Will this script work if the mouse cursor is needed to be locked to the centre of the screen? I am currently stuck using Input.mousePosition for having mouse control remotely instead of using Input.GetAxis() and I am having trouble when I am trying to use Cursor.lockState = CursorLockMode.Locked

@JAMS49
Copy link

JAMS49 commented Sep 6, 2021

The main prblm is ...It doesnt collide with any object...the camera just fly and pass through game objects and certainly it sucks....anyone is here to solve this problem?

@JAMS49
Copy link

JAMS49 commented Sep 6, 2021

using UnityEngine;

///

/// Unity Script to give camera WASD + mouse control
/// WASD : basic movement ; mouse directs the orientation of the view
/// Left Shift : Accelerate (as in running)
/// Space : Toggle moving camera on X and Z axes only.
///

/// Windexglow (11-13-2010), gunderson (2017)
///
public class FlyCamera : MonoBehaviour
{
///

/// regular speed
///

[Tooltip("Normal movement speed")]
public float mainSpeed = 100.0f;

/// <summary>
/// Running speed. Multiplied by how long (left) shift is held. 
/// if you dont want the extra speed, put here the same number as normal speed.
/// </summary>
[Tooltip("Acceleration when holding left shift")]
public float shiftAdd = 250.0f;

/// <summary>
/// Maximum speed when holding left shift
/// </summary>
[Tooltip("Maximum speed when holding left shift")]
public float maxShift = 1000.0f;

/// <summary>
/// mouse sensitivity 
/// </summary>
[Tooltip("mouse sensitivity")]
public float camSens = 0.25f;

/// <summary>
/// kind of in the middle of the screen, rather than at the top (play)
/// </summary>
private Vector3 lastMouse = new Vector3(255, 255, 255);
private float totalRun = 1.0f;

void Update()
{
    //calculate mouse view direction
    lastMouse = Input.mousePosition - lastMouse;
    lastMouse = new Vector3(-lastMouse.y * camSens, lastMouse.x * camSens, 0);
    lastMouse = new Vector3(transform.eulerAngles.x + lastMouse.x, transform.eulerAngles.y + lastMouse.y, 0);
    transform.eulerAngles = lastMouse;
    lastMouse = Input.mousePosition;
    //Mouse camera angle done.


    //Keyboard commands
    float f = 0.0f;
    Vector3 p = GetBaseInput(); //take WASD input from user

    if (Input.GetKey(KeyCode.LeftShift))
    {
        //if LeftShift -> Running mode
        totalRun += Time.deltaTime;
        p = p * totalRun * shiftAdd;
        p.x = Mathf.Clamp(p.x, -maxShift, maxShift);
        p.y = Mathf.Clamp(p.y, -maxShift, maxShift);
        p.z = Mathf.Clamp(p.z, -maxShift, maxShift);
    }
    else
    {
        //No Shift -> normal speed
        totalRun = Mathf.Clamp(totalRun * 0.5f, 1f, 1000f);
        p = p * mainSpeed;
    }

    p = p * Time.deltaTime;
    Vector3 newPosition = transform.position;
    if (Input.GetKey(KeyCode.Space))
    {
        //If player wants to move on X and Z axis only
        transform.Translate(p);
        newPosition.x = transform.position.x;
        newPosition.z = transform.position.z;
        transform.position = newPosition;
    }
    else
    {
        transform.Translate(p);
    }
}

/// <summary>
/// checks basic WASD input and put it in a Vector. if it's 0 than it's not active.
/// </summary>
/// <returns>Vector of all user input from WASD</returns>
private Vector3 GetBaseInput()
{ 
    Vector3 p_Velocity = new Vector3();
    if (Input.GetKey(KeyCode.W))
    {
        p_Velocity += new Vector3(0, 0, 1);
    }
    if (Input.GetKey(KeyCode.S))
    {
        p_Velocity += new Vector3(0, 0, -1);
    }
    if (Input.GetKey(KeyCode.A))
    {
        p_Velocity += new Vector3(-1, 0, 0);
    }
    if (Input.GetKey(KeyCode.D))
    {
        p_Velocity += new Vector3(1, 0, 0);
    }
    return p_Velocity;
}

}

is there any way to make the camera collide with other gameobjects or colliders>? please help me out.

@tungpt244
Copy link

Thank idols 😆😆

@HuKVK
Copy link

HuKVK commented Nov 18, 2021

Iea but how do i import da code im dumb

@gunderson
Copy link
Author

It's a monobehavior. Attach as a component to the game object you want to control.

@ONGHOST
Copy link

ONGHOST commented Nov 28, 2021

you saved the day , thank you a lot .

@ste-phil
Copy link

ste-phil commented Dec 10, 2021

Updated it with the following:

  • increase/decrease speed with the scrollwheel
  • rotating with right mouse button => locks & disables mouse cursor

`
public class SimpleCameraController : MonoBehaviour
{

    public float mainSpeed = 1.0f; //regular speed
    public float shiftAdd = 250.0f; //multiplied by how long shift is held.  Basically running
    public float maxShift = 1000.0f; //Maximum speed when holdin gshift
    public float camSens = 0.25f; //How sensitive it with mouse
    public bool invertY = true;

    public float scrollWheelSens = 1f;

    private Vector3 lastMouse = new Vector3(255, 255, 255); //kind of in the middle of the screen, rather than at the top (play)
    private float totalRun = 1.0f;

    void Update()
    {
        if (Input.GetMouseButton(1))
        {
            var mouseMoveY = invertY ? -1 * Input.GetAxis("Mouse Y") : Input.GetAxis("Mouse Y");
            var mouseMoveX = Input.GetAxis("Mouse X");

            var mouseMove = new Vector3(mouseMoveY, mouseMoveX, 0) * camSens;
            transform.eulerAngles = transform.eulerAngles + mouseMove;
        }

        if (Input.GetMouseButtonDown(1))
        {
            Cursor.visible = false;
            Cursor.lockState = CursorLockMode.Locked;
        }

        if (Input.GetMouseButtonUp(1))
        {
            Cursor.visible = true;
            Cursor.lockState = CursorLockMode.None;
        }

        //Mouse  camera angle done.  

        //Keyboard commands
        float f = 0.0f;
        Vector3 p = GetBaseInput();
        if (p.sqrMagnitude > 0)
        { // only move while a direction key is pressed
            if (Input.GetKey(KeyCode.LeftShift))
            {
                totalRun += Time.deltaTime;
                p = p * totalRun * shiftAdd;
                p.x = Mathf.Clamp(p.x, -maxShift, maxShift);
                p.y = Mathf.Clamp(p.y, -maxShift, maxShift);
                p.z = Mathf.Clamp(p.z, -maxShift, maxShift);
            }
            else
            {
                totalRun = Mathf.Clamp(totalRun * 0.5f, 1f, 1000f);
                p = p * mainSpeed;
            }

            p = p * Time.deltaTime;
            Vector3 newPosition = transform.position;
            if (Input.GetKey(KeyCode.Space))
            { //If player wants to move on X and Z axis only
                transform.Translate(p);
                newPosition.x = transform.position.x;
                newPosition.z = transform.position.z;
                transform.position = newPosition;
            }
            else
            {
                transform.Translate(p);
            }
        }

        var scroll = Input.GetAxis("Mouse ScrollWheel");
        mainSpeed += scroll * scrollWheelSens;
    }

    private Vector3 GetBaseInput()
    { //returns the basic values, if it's 0 than it's not active.
        Vector3 p_Velocity = new Vector3();
        if (Input.GetKey(KeyCode.W))
        {
            p_Velocity += new Vector3(0, 0, 1);
        }
        if (Input.GetKey(KeyCode.S))
        {
            p_Velocity += new Vector3(0, 0, -1);
        }
        if (Input.GetKey(KeyCode.A))
        {
            p_Velocity += new Vector3(-1, 0, 0);
        }
        if (Input.GetKey(KeyCode.D))
        {
            p_Velocity += new Vector3(1, 0, 0);
        }
        return p_Velocity;
    }`

@RiccardoCafiero
Copy link

Thank you! Great contribution

@AtomicRSA
Copy link

This works great.

Thanks dude!

@alexinorbit
Copy link

just what i needed ,thx

@JDRBL007
Copy link

JDRBL007 commented Jan 5, 2023

Is there anyway I can get the player to move the way the camera is facing? I am making a first person game.

@apoteet
Copy link

apoteet commented Jan 5, 2023

@JDRBL007 You should be able to attach this script and camera to your player. Then when the script updates the transform, that will adjust the player

@PellePetimeter
Copy link

PellePetimeter commented Feb 16, 2023

Thank's for sharing. Saved me a lot of work.
I made a modification that makes it posible to deactivate the flycamera by hitting esc, and activate it again by hitting F1. I think it's usefull if you want's to modify something in the scene while keeping the cameraposition fixed.

I'm sure there's a better way to implement this but it works.

void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
activeFlyCamera = false;
savedCameraPosition = Camera.main.transform.eulerAngles;
savedCameraRotation = Camera.main.transform.rotation;
}

    if (Input.GetKey(KeyCode.F1))
    {
        activeFlyCamera = true;
        Camera.main.transform.eulerAngles = savedCameraPosition;
        Camera.main.transform.rotation = savedCameraRotation;
    }
        

    if (activeFlyCamera)
    {

@DawPiot14
Copy link

Is there a way to make this script work with Rigid body? Or is there any other way to make the object collide with the camera and not just let it fly through?

Copy link

ghost commented Jul 2, 2023

Just needed a quick script for testing in play mode so I didn't have to rely on fixed camera positions and this works great for that. Thank you very much.

@gunderson
Copy link
Author

gunderson commented Jul 3, 2023 via email

@JulianLeo
Copy link

It's really close to what I was looking for. With some adjustments, it does what I need it for. Very neat!

@LennartSBR
Copy link

i dont know if i am the only one but it simply doesnt work. i cheked unity official tutorials and copied the code they wrote, but didnt work. please someone help me. PS: using 2020.2.6f1

Did you name the file FlyCamera.cs?
You need to replace FlyCamera if you use another name.

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