Skip to content

Instantly share code, notes, and snippets.

@ashleydavis
Last active November 14, 2024 14:46
Show Gist options
  • Save ashleydavis/f025c03a9221bc840a2b to your computer and use it in GitHub Desktop.
Save ashleydavis/f025c03a9221bc840a2b to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
/// <summary>
/// A simple free camera to be added to a Unity game object.
///
/// Keys:
/// wasd / arrows - movement
/// q/e - up/down (local space)
/// r/f - up/down (world space)
/// pageup/pagedown - up/down (world space)
/// hold shift - enable fast movement mode
/// right mouse - enable free look
/// mouse - free look / rotation
///
/// </summary>
public class FreeCam : MonoBehaviour
{
/// <summary>
/// Normal speed of camera movement.
/// </summary>
public float movementSpeed = 10f;
/// <summary>
/// Speed of camera movement when shift is held down,
/// </summary>
public float fastMovementSpeed = 100f;
/// <summary>
/// Sensitivity for free look.
/// </summary>
public float freeLookSensitivity = 3f;
/// <summary>
/// Amount to zoom the camera when using the mouse wheel.
/// </summary>
public float zoomSensitivity = 10f;
/// <summary>
/// Amount to zoom the camera when using the mouse wheel (fast mode).
/// </summary>
public float fastZoomSensitivity = 50f;
/// <summary>
/// Set to true when free looking (on right mouse button).
/// </summary>
private bool looking = false;
void Update()
{
var fastMode = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
var movementSpeed = fastMode ? this.fastMovementSpeed : this.movementSpeed;
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
transform.position = transform.position + (-transform.right * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
transform.position = transform.position + (transform.right * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
transform.position = transform.position + (transform.forward * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
transform.position = transform.position + (-transform.forward * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.Q))
{
transform.position = transform.position + (transform.up * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.E))
{
transform.position = transform.position + (-transform.up * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.R) || Input.GetKey(KeyCode.PageUp))
{
transform.position = transform.position + (Vector3.up * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.F) || Input.GetKey(KeyCode.PageDown))
{
transform.position = transform.position + (-Vector3.up * movementSpeed * Time.deltaTime);
}
if (looking)
{
float newRotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * freeLookSensitivity;
float newRotationY = transform.localEulerAngles.x - Input.GetAxis("Mouse Y") * freeLookSensitivity;
transform.localEulerAngles = new Vector3(newRotationY, newRotationX, 0f);
}
float axis = Input.GetAxis("Mouse ScrollWheel");
if (axis != 0)
{
var zoomSensitivity = fastMode ? this.fastZoomSensitivity : this.zoomSensitivity;
transform.position = transform.position + transform.forward * axis * zoomSensitivity;
}
if (Input.GetKeyDown(KeyCode.Mouse1))
{
StartLooking();
}
else if (Input.GetKeyUp(KeyCode.Mouse1))
{
StopLooking();
}
}
void OnDisable()
{
StopLooking();
}
/// <summary>
/// Enable free looking.
/// </summary>
public void StartLooking()
{
looking = true;
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
/// <summary>
/// Disable free looking.
/// </summary>
public void StopLooking()
{
looking = false;
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
}
@suprafun
Copy link

Hello, under what license is this script released under ? Thank-you.

@ashleydavis
Copy link
Author

Sorry I don't usually bother licencing gists.

Consider it an MIT licence. That's what I normally use for repos.

@umustbeloggedintododat
Copy link

how do I put this in an apk?

@ashleydavis
Copy link
Author

You mean an Android app?

You might want to start with a tutorial on building Android apps with Unity.

@jeffman1
Copy link

jeffman1 commented Jan 5, 2021

I love the code! I revised it to put the player back at their original position afterwards to keep them from being distracted in the game. However, it does work with some modifications with the 3rd person script. I only kept the rotation code so I could free look without the rest of the 3rd person script interfering. It works perfectly with my other code! Using Unity 2019.3 because my models from Character Creator do not work with Unity 2020 and above yet (something is buggy still about 2020 in my opinion).

@ashleydavis
Copy link
Author

Awesome. I'm glad this code is still useful!

@Raken23
Copy link

Raken23 commented Jan 10, 2022

Great thing! Exactly what I expected. Thank you.

@JelleWolbers
Copy link

This is awesome, exactly what I needed, thanks! By the way, I think the only namespace you need to include is UnityEngine, the rest doesn't seem to be necessary ;)

@ashleydavis
Copy link
Author

Cool, thanks for letting me know! The other stuff is just standard .NET imports that are included by default ;)

@Oppodelldog
Copy link

I wanted to have Q and E behave same like Unity does, actually for me it's the other way round.

    /// <summary>
    /// Normal speed of vertical camera movement (keys Q,E).
    /// </summary>
    public float verticalMovement = 10f;

and use it for Q and E

            if (Input.GetKey(KeyCode.Q))
            {
                transform.position = transform.position + (transform.up * verticalMovement * Time.deltaTime);
            }

            if (Input.GetKey(KeyCode.E))
            {
                transform.position = transform.position + (-transform.up * verticalMovement * Time.deltaTime);
            }

This is backward compatible solution; To get the Unity behavior you need to put -10 in the Properties Editor.

@LucasFA
Copy link

LucasFA commented Aug 15, 2022

Hello, under what license is this script released under ? Thank-you.

if this was under license, it would have been stated and it is highly likely it wouldn't have been posted so openly

FYI, by default things are all rights reserved, not free to use as one might think. See this and this open source stack questions

@ashleydavis
Copy link
Author

I've already stated that this code is released with the MIT licence, please use it however you like.

@ashleydavis
Copy link
Author

how to use code?

This is a Unity component.

Start Unity. Add a Game Object to the scene. Add this component to the Game Object.

@ashleydavis
Copy link
Author

Start Unity. Add a Game Object to the scene. Add this component to the Game Object.

@ashleydavis
Copy link
Author

Are you able to just add code to Unity games? I don't believe it's possible to do that, unless you already have the code for the game. But feel free to do some research for yourself.

@wartron
Copy link

wartron commented Aug 6, 2024

Thanks for this, mostly works, but i noticed in look mode, directly up and down kinda glitches out.

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