# Resize a moving viewport (avoiding getting squeezed at the screen bounds)

Greetings, everyone! After many searches and attempts related to a problem that’s driving me crazy, I decided to create a topic for search a help.

The situation is this: I’m working with the viewport of a camera that will be shown for the main camera on the same coordinates and measures of a sprite that will be moved on the screen. So far, all right; I managed to solve this problem using the following code in each update:

``````cam.pixelRect = new Rect (pos.x, pos.y, sprite_width, sprite_height);
``````

The problem is that, when part of the sprite is offscreen, the viewport doesn’t follow it; rather, it’s “squeezed” on the screen bounds.

I searched the internet for days, and basically found the same code to solve this problem, using projectionMatrix. Here it:

``````  void OnPreRender()
{
var r = new Rect(0f, 0f, 1f, 1f);
var alignFactor = Vector2.one;
if (offset.y >= 0f)
{
// Sliding down
r.height = 1f - offset.y;
alignFactor.y = 1f;
}
else
{
// Sliding up
r.y = -offset.y;
r.height = 1f + offset.y;
alignFactor.y = -1f;
}

if (offset.x >= 0f)
{
// Sliding right
r.width = 1f - offset.x;
alignFactor.x = 1f;
}
else
{
// Sliding left
r.x = -offset.x;
r.width = 1f + offset.x;
alignFactor.x = -1f;
}

// Avoid division by zero
if (r.width == 0f)
{
r.width = 0.001f;
}
if (r.height == 0f)
{
r.height = 0.001f;
}

// Set the camera's render rectangle to r, but use the normal projection matrix
// This works around Unity modifying the projection matrix to correct for the aspect ratio
// (which is normally desirable behaviour, but interferes with this effect)
camera.rect = new Rect(0,0,1,1);
camera.ResetProjectionMatrix();
Matrix4x4 m = camera.projectionMatrix;
camera.rect = r;

// The above has caused the scene render to be squashed into the rectangle r.
// Apply a scale factor to un-squash it.
// The translation factor aligns the top of the scene to the top of the view
// (without this, the view is of the middle of the scene)
Matrix4x4 m2 = Matrix4x4.TRS(
new Vector3(alignFactor.x * (-1/r.width + 1), alignFactor.y * (-1/r.height + 1), 0),
Quaternion.identity,
new Vector3 (1/r.width, 1/r.height, 1));

camera.projectionMatrix = m2 * m;
}
}
``````

The above code works perfectly, but I have no idea how to change the size of the viewport (with this code, the viewport always remains in 1:1).

Any idea about how to modify this code will be welcome. Thanks for your attention, and sorry for my poor english!

Did you try to put in your desired rectangle in line 46: camera.rect=newRect(0,0,1,1); ? Got not much time to test your code, but this would be one thing for me to start with. trial and error.

Thanks for answering!
So, I have done several attempts, but never reach what I want. In the case of line 46, “cam.rect” is just being started. It receives “r” Rect in line 49, with the values properly modified in the initial conditions.
Cheers!

Hi Abvabv,

I know its been a while, but wanted to check if you ever got to the bottom of this?

I have also been trying to resolve the same problem. So much so that I made an example project which can be checked out here:
https://bitbucket.org/danieldownes/recttransformviewport/src/abd9f907cfb6dd8153a3031a6898088df3caceca/Assets/SetViewportToUiRect.cs?at=master&fileviewer=file-view-default

Thank you for any help.