Pan, Zoom and limit camera movement - Unity 2D Tutorial
HTML-код
- Опубликовано: 11 сен 2020
- Learn a quick and simple method to move your camera by dragging around with the mouse or finger, how to zoom in and out, and how to limit your camera range to a sprite or a tile.
This is useful when you have a camera that the player can move around like in my example, but also when you want a camera to follow a game character, because chances are when you hit the edge of the game world, you want the camera to stop following.
If you want to restrict camera movement to only when the mouse is not over an UI element, check out this video: • Custom Click Manager -...
Please check out my newest game Idle Potato Power. It's a fun and relaxing game about exploring Potato Power in all it's multidimensional weirdness.
play.google.com/store/apps/de...
github.com/ShackMan2000
Discord: / discord
Great video. Thanks for all of the details and explanations, as opposed to just instructions on what to do. You made it easy to understand why things are happening, not just what is happening.
Thanks!
Thanks for the video, everything works. I am pasting the code for others:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMovement : MonoBehaviour
{
[SerializeField]
private Camera cam; //obiekt kamery
[SerializeField]
private float zoomStep, minCamSize, maxCamSize; //zakres powiększenia
[SerializeField]
private SpriteRenderer mapRenderer;
private float mapMinX, mapMaxX, mapMinY, mapMaxY;
private Vector3 dragOrigin;
private void Awake()
{
mapMinX = mapRenderer.transform.position.x - mapRenderer.bounds.size.x / 2f;
mapMaxX = mapRenderer.transform.position.x + mapRenderer.bounds.size.x / 2f;
mapMinY = mapRenderer.transform.position.y - mapRenderer.bounds.size.y / 2f;
mapMaxY = mapRenderer.transform.position.y + mapRenderer.bounds.size.y / 2f;
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
PanCamera();
}
//przesuwanie pozycji kamery (lewo, prawo, góra, dół)
private void PanCamera()
{
if (Input.GetMouseButtonDown(0))
dragOrigin = cam.ScreenToWorldPoint(Input.mousePosition);
if (Input.GetMouseButton(0))
{
Vector3 difference = dragOrigin - cam.ScreenToWorldPoint(Input.mousePosition);
print("origin " + dragOrigin + " newPosition " + cam.ScreenToWorldPoint(Input.mousePosition) + " =difference" + difference);
//cam.transform.position += difference; //bez ograniczenia obszaru
cam.transform.position = ClampCamera(cam.transform.position + difference); //ograniczenie obszaru
}
/*
if (Input.GetMouseButtonDown(0)) dragOrigin = cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, cam.transform.position.z * -1));
if (Input.GetMouseButton(0))
{
Vector3 difference = dragOrigin - cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, cam.transform.position.z * -1));
Debug.Log("origin " + dragOrigin + " newPosition " + cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, cam.transform.position.z * -1)) + " =difference " + difference);
cam.transform.position += new Vector3(difference.x, difference.y, 0f);
}
*/
}
public void ZoomIn()
{
float newSize = cam.orthographicSize - zoomStep;
cam.orthographicSize = Mathf.Clamp(newSize, minCamSize, maxCamSize);
cam.transform.position = ClampCamera(cam.transform.position); //ograniczenie obszaru
}
public void ZoomOut()
{
float newSize = cam.orthographicSize + zoomStep;
cam.orthographicSize = Mathf.Clamp(newSize, minCamSize, maxCamSize);
cam.transform.position = ClampCamera(cam.transform.position); //ograniczenie obszaru
}
private Vector3 ClampCamera(Vector3 targetPosition)
{
float camHeight = cam.orthographicSize;
float camWidth = cam.orthographicSize * cam.aspect;
float minX = mapMinX + camWidth;
float maxX = mapMaxX - camWidth;
float minY = mapMinY + camHeight;
float maxY = mapMaxY - camHeight;
float newX = Mathf.Clamp(targetPosition.x, minX, maxX);
float newY = Mathf.Clamp(targetPosition.y, minY, maxY);
return new Vector3(newX, newY, targetPosition.z);
}
}
polska gurom
Just came by to leave a like. Thank you Sir! Everything i needed in a straight to the point video.
Man, you saved me hours. One of the best and clear explanation.
thats exactly what i needed man that was awesome. I used DOTween for the zoom animation which makes it feel a lot smoother
Thank you man, was searching for ever to find something like this video. Helped a lot!
Amazing and useful tutorial brother, thank you for the great content.
Awesome tutorial, needed something to make sure the camera's corners didn't go outside the boundaries regardless of zoom size and this did the trick! :D
These tutorials are useful and simple, Thanks for this!
who would have guessed that I would stumble upon the exact tutorial I need! Thanks!!
Probably the youtube algorithm that already knows what you're gonna need next week ;-)
thnx so much man been struggling for about like 4 hours now tysm!!!
Great tutorial. Helped me save a lot of time. Thanks a lot!!
That was exactly what i searched for, thank you very much
Thank you very much for the tutorial !!! Helped me a lot
These are good tutorials. I like the tilemap ones too.
sir u have any idea of canvas move with mouse
sir pls reply
WoW~! Thank you so much! This helped me a lot to start a new project!
A huge thanks for this awesome help!
Thanks a lot for this. It's a big help. Keep up the good work.
Thanks!
Awesome video, it really helped me a lot!
Thank you very much. Great tutorial + save a lot of time.
Great tutorial
Managed to hold my picture in the center on maximal zoomout by changing two lines:
float minX = mapMinX + Mathf.Min(camWidth, mapRender.bounds.size.x / 2f);
float maxX = mapMaxX - Mathf.Min(camWidth, mapRender.bounds.size.x / 2f);
really useful tutorial, thanks a lot friend
THANK YOU! My breakthrough (learned from you) came when using a sprite, to set the borders of the camera movement!
Great tutorial! Thanks!
Another idea for the zoom-out clamp:
- Add the code below at the end of zoom out function:
_cam.transform.position = ClampCamera(_camera.transform.position);
Thank you, helped me alot!
Hi, love the video. Just a question, how would you go about clamping the position of the camera if you are using a UI RawImage instead of a SpriteRenderer?
For anyone who wants to zoom in/out with the mouse wheel and clamp the size of the camera to the width of the map, I think this is right? Maybe Shack Man can let me know. It works for me:
void Update()
{
if (Input.GetAxis("Mouse ScrollWheel") > 0f) { ZoomIn(); }
if (Input.GetAxis("Mouse ScrollWheel") < 0f) { ZoomOut(); }
}
private void ZoomIn()
{
float newSize = cam.orthographicSize - zoomStep;
cam.orthographicSize = Mathf.Clamp(newSize, minCamSize, Mathf.Min(maxCamSize, (mapRenderer.bounds.size.x / 2f) / cam.aspect));
cam.transform.position = ClampCamera(cam.transform.position);
}
private void ZoomOut()
{
float newSize = cam.orthographicSize + zoomStep;
cam.orthographicSize = Mathf.Clamp(newSize, minCamSize, Mathf.Min(maxCamSize, (mapRenderer.bounds.size.x / 2f) / cam.aspect));
cam.transform.position = ClampCamera(cam.transform.position);
}
Thank you!
tysm
best tutorial on this, thank you
Different engines, same logic. Thanks!
anyone who needs a scroll wheel to zoom in and out add this in the update function
if (Input.GetAxis("Mouse ScrollWheel") > 0f) // forward
{
ZoomIn();
}
else if (Input.GetAxis("Mouse ScrollWheel") < 0f) // backwards
{
ZoomOut();
}
Thanks
Hi thanks for the video, do you have any ideas how I could add an offset camera to the limit for the UI panel?
How would you make the pan go farther than the mouse, like when dragging it will move past the mouse position?
Camera coded in 10 minutes thanks you
It Works like a charm, but I don´t have an image to do it, so I used 2 Vector2 to adjust the borders. TY
all works perfectly
Hi, How would you adjust the clamp if using a perspective camera instead of orthogonal ?
many thanks in advance.
i want to use tilemap instead of sprite renderer, how can i do it?
Can you please explain the last part. How to not zoom beyond the map?!
I want build big soace level. How canni do borders when ship cant move?
Thank you for this video but i got a problem ut sometimes turn blue or the sprite turn invisible sometimes im still looking for solutions 😢
Thanks a lot!
This is better way to create bounds then use Cinemachine
Thanks a lot!
You are amazing
can you please explain how origin point and newPosition become same after some time. despite position on screen is different than origin position
Awesome 👍
Thank you!!!
thank you so much
man you are amazing
How to convert to the zoom wheel?
ty very very much
Why I cannot see "ScreenToWorldPoint" in my Unity ? do I need to add it somehow ?
¡gracias!
How are minCamSize and maxCamSize set? Since they're private it won't show in the inspector, right?
you can with the SerializeField, they appear in the Inspector
Works in mobile devices?
Can you make a tutorial for this with the new imput system?
warning CS0649: Field `CameraZoomAnd2dMap.maxCamSize' is never assigned to, and will always have its default value `0'
sir pls reply i have get this error
Sir pls reply
Do anyone know how Can I do this with cinemachine camera
hi, im only need pan and boundary but somehow I can't get the boundary working any idea why?
also i only want to pan on the x axis and the y axis just staying still
On a mobile device the camera jitters around when detecting multiple touches or if I tap around on the screen. Is there a simple solution to this issue? Thank you
Yooo I have the same problem. I've tried multiple tutoriakls here on youtube and they all have the same problem. The camera bounces around on mobile when you tap the screen making it unusuable. Game Dev Shack HELP USSSS!!!
I'll take a look at it tomorrow, I hadn't tried it on an actual mobile device yet. What exactly do you mean with multiple touches? like you put down two fingers as if you were going for a pinch and then the camera jumps between those 2 fingers?
@@ShackMan if you tap the screen repeatedly on either side the camera jitters dramatically and is unstable. Tap the left side of the screen and the right side of the screen quickly simultaneously for instance and you'll see the camera jitter. Thank you for getting back to me. If you can help solve this issue I would very much appreciate it
I've tried it out and it works fine for me... What you describe could be that the camera is bigger than the limits? In my example I'm using free aspect ratio, so depending on your phone the camera might be larger (either horizontal or vertical or both) than the sprite it is limited to. You could try to remove the limit or set the camera to be really small, then build the apk and try again. Let me know if it works!
can you link the script file, its very cumbersome to rewrite the whole thing if i make a mistake.
also my camera keeps jittering when i move it in game, whats going on?
Have you solved this problam? I have the same.
@@Jarzykk sadly not yet, I think I have an idea, tho it's not concrete as i dont have a copy of the code directly to compare properly
It may have something to do with swapping x and z, plus this is completely useless if you use the new input
@@bioman1hazard607 Thank you for the answer, Artemis!
will this work for 3D camera as well?
no, sorry.
i need to make the zoom with mouse wheel how ??
if (Input.GetAxis("Mouse ScrollWheel") > 0f)
{
ZoomIn();
}
else if (Input.GetAxis("Mouse ScrollWheel") < 0f)
{
ZoomOut();
}
does it work in 3D? Your example is a plane (map)
The principal is the same, you check how much the mouse has moved and apply that to the camera, but you would have to adjust some stuff. For one 3D cameras are a lot more diverse than 2D cameras.
I tried to use the first part of the code with just the camera movement but it didnt work for me. I got the console output but my camera didnt move. anyone got an idea?
Same problem.
Make sure your camera is on orthographic projection
im having the same issue. my camera is set up correctly in orth view and code is correct as well
Problem you can’t press buttons when having this script active
did you figure out a fix
You are god
Please tell me how to make it smoothness?
That there would be smoothness in the movement of the camera, that it would look alive
by probably creating a vector of the direction youre moving it and moving it with a delay using time.DeltaTime
Vector3.Lerp
@@fodk7021 Where do you put it?
i tried the code, but why my camera is not moving? any help
It didn't work for me either. CHeck your code, it worked after i found out i missed private and big letter U in private void Update ;)
@@TheTrolderia it doesn't work tho and it can't work ScreenToWorldPoint takes a Vector3 not a Vector2
You really know you can trust someone if he uses 5 exclamation marks and two "1"s to make a point.
Eh😞 that would be like this for android (touchscreen)
Doing all that and then not explaining the last part really ruins what was a really a good video.
didnt work
camera cant move :(
oh i change ortohgraphic camera fixed.
@@User-nt9oc have you used the latest version of unity?
nevermind, it started to work somehow
red
just for anyone who wants zoom when you scroll with the mouse:
void zoom()
{
if (Input.GetAxis("Mouse ScrollWheel") > 0f)
{
float newSize = mainCamera.orthographicSize - zoomStep;
mainCamera.orthographicSize = Mathf.Clamp(newSize, minCameraSize, maxCameraSize);
}
else if (Input.GetAxis("Mouse ScrollWheel") < 0f)
{
float newSize = mainCamera.orthographicSize + zoomStep;
mainCamera.orthographicSize = Mathf.Clamp(newSize, minCameraSize, maxCameraSize);
}
mainCamera.transform.position = clampCamera(mainCamera.transform.position);
}