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

Комментарии • 113

  • @cocopjojo
    @cocopjojo 3 года назад +11

    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.

  • @piotrek228
    @piotrek228 2 года назад +37

    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);
    }
    }

  • @Fresch1990
    @Fresch1990 3 года назад +1

    Just came by to leave a like. Thank you Sir! Everything i needed in a straight to the point video.

  • @victorkuzmin3416
    @victorkuzmin3416 8 месяцев назад +1

    Man, you saved me hours. One of the best and clear explanation.

  • @urselhorst9253
    @urselhorst9253 9 месяцев назад

    thats exactly what i needed man that was awesome. I used DOTween for the zoom animation which makes it feel a lot smoother

  • @sergejlopatkin3149
    @sergejlopatkin3149 2 года назад

    Thank you man, was searching for ever to find something like this video. Helped a lot!

  • @technoo4891
    @technoo4891 3 года назад +4

    Amazing and useful tutorial brother, thank you for the great content.

  • @WishMakerDX
    @WishMakerDX 3 года назад +5

    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

  • @Rexcode
    @Rexcode 3 года назад +2

    These tutorials are useful and simple, Thanks for this!

  • @bartmanp.4734
    @bartmanp.4734 3 года назад +1

    who would have guessed that I would stumble upon the exact tutorial I need! Thanks!!

    • @ShackMan
      @ShackMan  3 года назад +1

      Probably the youtube algorithm that already knows what you're gonna need next week ;-)

  • @aminacrawford9761
    @aminacrawford9761 Год назад +1

    thnx so much man been struggling for about like 4 hours now tysm!!!

  • @jayanth2209
    @jayanth2209 3 года назад +2

    Great tutorial. Helped me save a lot of time. Thanks a lot!!

  • @irgendein2.account432
    @irgendein2.account432 3 года назад

    That was exactly what i searched for, thank you very much

  • @valeriag.3324
    @valeriag.3324 Год назад

    Thank you very much for the tutorial !!! Helped me a lot

  • @kulhain
    @kulhain 3 года назад +1

    These are good tutorials. I like the tilemap ones too.

    • @indiandev1588
      @indiandev1588 2 года назад +1

      sir u have any idea of canvas move with mouse
      sir pls reply

  • @0_0hyunni
    @0_0hyunni Месяц назад

    WoW~! Thank you so much! This helped me a lot to start a new project!

  • @shiyaromischannel9542
    @shiyaromischannel9542 3 года назад

    A huge thanks for this awesome help!

  • @dudelios3123
    @dudelios3123 2 года назад

    Thanks a lot for this. It's a big help. Keep up the good work.

  • @shung0209
    @shung0209 2 года назад

    Awesome video, it really helped me a lot!

  • @1nexts
    @1nexts 2 года назад

    Thank you very much. Great tutorial + save a lot of time.

  • @user-vz2il5du2c
    @user-vz2il5du2c Месяц назад

    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);

  • @Ghost-2079
    @Ghost-2079 2 года назад

    really useful tutorial, thanks a lot friend

  • @lordheman
    @lordheman 2 года назад

    THANK YOU! My breakthrough (learned from you) came when using a sprite, to set the borders of the camera movement!

  • @mihailmalikov7538
    @mihailmalikov7538 3 года назад

    Great tutorial! Thanks!

  • @YayapipiStudio
    @YayapipiStudio Год назад

    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);

  • @dmytrokorsunskyi
    @dmytrokorsunskyi 3 года назад

    Thank you, helped me alot!

  • @podrix
    @podrix Год назад +1

    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?

  • @andrewgray9797
    @andrewgray9797 Год назад +4

    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);
    }

  • @munchkis
    @munchkis Месяц назад

    best tutorial on this, thank you

  • @DanutJMK
    @DanutJMK 8 месяцев назад

    Different engines, same logic. Thanks!

  • @friesneverdies
    @friesneverdies 2 года назад +7

    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();
    }

  • @andreyrosiaev8613
    @andreyrosiaev8613 Год назад

    Hi thanks for the video, do you have any ideas how I could add an offset camera to the limit for the UI panel?

  • @thePRODYLAN
    @thePRODYLAN 2 года назад +1

    How would you make the pan go farther than the mouse, like when dragging it will move past the mouse position?

  • @kyokaishiro7944
    @kyokaishiro7944 2 года назад

    Camera coded in 10 minutes thanks you

  • @renata_navarro
    @renata_navarro 9 месяцев назад

    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

  • @well5832
    @well5832 3 года назад

    all works perfectly

  • @palanolho82
    @palanolho82 6 месяцев назад

    Hi, How would you adjust the clamp if using a perspective camera instead of orthogonal ?
    many thanks in advance.

  • @bilgipaylasmplatformu8454
    @bilgipaylasmplatformu8454 2 года назад

    i want to use tilemap instead of sprite renderer, how can i do it?

  • @AleySoundz
    @AleySoundz Год назад +1

    Can you please explain the last part. How to not zoom beyond the map?!

  • @spikeweb5193
    @spikeweb5193 Год назад

    I want build big soace level. How canni do borders when ship cant move?

  • @anima9266
    @anima9266 8 месяцев назад

    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 😢

  • @WanP1su
    @WanP1su 2 года назад

    Thanks a lot!
    This is better way to create bounds then use Cinemachine

  • @mrussoart
    @mrussoart 10 месяцев назад

    Thanks a lot!

  • @ShakerFS
    @ShakerFS 2 года назад

    You are amazing

  • @GamingTherapy8890
    @GamingTherapy8890 4 месяца назад

    can you please explain how origin point and newPosition become same after some time. despite position on screen is different than origin position

  • @vanshtandon1829
    @vanshtandon1829 2 месяца назад

    Awesome 👍

  • @niqita_draws
    @niqita_draws 2 года назад

    Thank you!!!

  • @thanhduyphan2234
    @thanhduyphan2234 3 года назад

    thank you so much

  • @guest7play614
    @guest7play614 Год назад

    man you are amazing

  • @darknside
    @darknside Год назад

    How to convert to the zoom wheel?

  • @DavidAdochiti
    @DavidAdochiti 2 года назад

    ty very very much

  • @stiluboy
    @stiluboy 8 месяцев назад

    Why I cannot see "ScreenToWorldPoint" in my Unity ? do I need to add it somehow ?

  • @mauriciograsso8102
    @mauriciograsso8102 2 года назад

    ¡gracias!

  • @lilbocheap139
    @lilbocheap139 2 года назад

    How are minCamSize and maxCamSize set? Since they're private it won't show in the inspector, right?

    • @ormar4564
      @ormar4564 Год назад

      you can with the SerializeField, they appear in the Inspector

  • @Ffiree
    @Ffiree 2 года назад

    Works in mobile devices?

  • @cake8242
    @cake8242 9 дней назад

    Can you make a tutorial for this with the new imput system?

  • @indiandev1588
    @indiandev1588 2 года назад +1

    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

  • @alperakin2561
    @alperakin2561 7 часов назад

    Do anyone know how Can I do this with cinemachine camera

  • @anellaa5070
    @anellaa5070 9 месяцев назад

    hi, im only need pan and boundary but somehow I can't get the boundary working any idea why?

    • @anellaa5070
      @anellaa5070 9 месяцев назад

      also i only want to pan on the x axis and the y axis just staying still

  • @kaiserium
    @kaiserium 3 года назад +1

    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

    • @nustalljic8913
      @nustalljic8913 3 года назад +1

      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!!!

    • @ShackMan
      @ShackMan  3 года назад

      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?

    • @kaiserium
      @kaiserium 3 года назад

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

    • @ShackMan
      @ShackMan  3 года назад

      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!

  • @bioman1hazard607
    @bioman1hazard607 3 года назад +3

    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?

    • @Jarzykk
      @Jarzykk 3 года назад

      Have you solved this problam? I have the same.

    • @bioman1hazard607
      @bioman1hazard607 3 года назад +1

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

    • @bioman1hazard607
      @bioman1hazard607 3 года назад

      It may have something to do with swapping x and z, plus this is completely useless if you use the new input

    • @Jarzykk
      @Jarzykk 3 года назад +1

      @@bioman1hazard607 Thank you for the answer, Artemis!

  • @sanketvaria9734
    @sanketvaria9734 2 года назад +1

    will this work for 3D camera as well?

  • @ahmed74kkk
    @ahmed74kkk 2 года назад

    i need to make the zoom with mouse wheel how ??

    • @thomasbjrnkrogh-jacobsen6391
      @thomasbjrnkrogh-jacobsen6391 2 года назад

      if (Input.GetAxis("Mouse ScrollWheel") > 0f)
      {
      ZoomIn();
      }
      else if (Input.GetAxis("Mouse ScrollWheel") < 0f)
      {
      ZoomOut();
      }

  • @softwarecprogrammieren
    @softwarecprogrammieren Год назад

    does it work in 3D? Your example is a plane (map)

    • @ShackMan
      @ShackMan  Год назад

      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.

  • @lennardfischomode1940
    @lennardfischomode1940 2 года назад +4

    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?

    • @GenJeFT
      @GenJeFT Год назад

      Same problem.

    • @chrissmalls4462
      @chrissmalls4462 Год назад

      Make sure your camera is on orthographic projection

    • @tommedenney
      @tommedenney Год назад

      im having the same issue. my camera is set up correctly in orth view and code is correct as well

  • @foxzyx
    @foxzyx 2 года назад

    Problem you can’t press buttons when having this script active

  • @AAAlexGames
    @AAAlexGames 2 года назад

    You are god

  • @lora6938
    @lora6938 3 года назад

    Please tell me how to make it smoothness?
    That there would be smoothness in the movement of the camera, that it would look alive

    • @SlitDiver
      @SlitDiver 3 года назад

      by probably creating a vector of the direction youre moving it and moving it with a delay using time.DeltaTime

    • @fodk7021
      @fodk7021 3 года назад

      Vector3.Lerp

    • @DevCoreFelix
      @DevCoreFelix 2 года назад

      @@fodk7021 Where do you put it?

  • @hardcodednoob4645
    @hardcodednoob4645 3 года назад +1

    i tried the code, but why my camera is not moving? any help

    • @TheTrolderia
      @TheTrolderia 3 года назад

      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 ;)

    • @fodk7021
      @fodk7021 3 года назад

      @@TheTrolderia it doesn't work tho and it can't work ScreenToWorldPoint takes a Vector3 not a Vector2

  • @disobedientdolphin
    @disobedientdolphin Год назад

    You really know you can trust someone if he uses 5 exclamation marks and two "1"s to make a point.

  • @lora6938
    @lora6938 3 года назад

    Eh😞 that would be like this for android (touchscreen)

  • @tyberius1313
    @tyberius1313 2 года назад +3

    Doing all that and then not explaining the last part really ruins what was a really a good video.

  • @cinemamovies1916
    @cinemamovies1916 Год назад

    didnt work

  • @User-nt9oc
    @User-nt9oc Год назад

    camera cant move :(

    • @User-nt9oc
      @User-nt9oc Год назад

      oh i change ortohgraphic camera fixed.

    • @quartal9588
      @quartal9588 Год назад

      @@User-nt9oc have you used the latest version of unity?

    • @quartal9588
      @quartal9588 Год назад

      nevermind, it started to work somehow

  • @atomiz2002
    @atomiz2002 2 года назад

    red

  • @davidmartin3772
    @davidmartin3772 Год назад

    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);
    }