Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do I clamp a perspective cameras viewport?

Discussion in 'Scripting' started by mrCharli3, Jan 16, 2022.

  1. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    I have a map laying on a table, and a perspective camera at a 95 degree angle looking at it, I can zoom the camera in and out and move it around.

    Since I can zoom in and out, simply clamping the camera position is not enough, I need to clamp the actual viewport.

    Here is an example:

    - Brown is the table
    - Green is the map
    - Red is the camera viewport
    - Orange Is the clamping boundries.

    No matter the zoom, I never want the camera viewport to leave the orange boundries. How can I achieve this?

    upload_2022-1-16_13-7-55.png
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,517
    I've said it before, I'll say it again... Camera stuff is pretty tricky... you may wish to consider using Cinemachine from the Unity Package Manager.
     
  3. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    I really dislike cinemachine, it’s great for a free look camera in an rpg but in a top down rts it is just not good. I made my own camera controller that works perfectly for all I need, I only have this last thing I can’t figure out.
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Is the boundaries aligned with the camera? And is the camera at a fixed angle?

    In that case you can do a relatively simple thing:
    - Position your camera at an arbitrary position that's at your wanted height and angle
    - Create a Plane that matches the table (same height, pointing straight up)
    - Check the intersection of that plane with a viewport ray in the top of the camera

    For example, the point calculated here is the point at which the upper left of the viewport intersects with the table plane:
    Code (csharp):
    1. var ray = mainCamera.ViewportPointToRay(new Vector3(-1f, 1f));
    2. groundPlane.Raycast(ray, out var distance);
    3. var point = ray.origin + distance * ray.direction;
    - calculate the z-distance between the current camera position and that point. This is how close you can be to the upper edge of your clamping boundary on the z-axis

    You can similarly do the same thing for other corners and the x-axis to find how far you can be from all the sides. Use that again to construct some Bounds so you can easily clamp your camera by just doing Bounds.ClosestPointOnBounds on the wanted position.
     
    javaduan and Bunny83 like this.
  5. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    OOOH, yes this should work! Thank you :)