Having more than one viewport displayed can be useful in many situations. For example, you may want to show simultaneous events going on in different locations, or you may want to have a separate window for hot-seat multiplayer games. Although you can do this manually by adjusting the Normalized Viewport Rect parameters on your camera, this recipe includes a series of extra preferences to make it more independent from the user's display configuration.
For this recipe, we have prepared the BasicScene
Unity package, containing a scene named BasicScene
. The package is in the 1362_05_codes
folder.
To create a picture-in-picture display, just follow these steps:
BasicScene
package into your Unity Project.PictureInPicture
.using UnityEngine; public class PictureInPicture: MonoBehaviour { public enum hAlignment{left, center, right}; public enum vAlignment{top, middle, bottom}; public hAlignment horAlign = hAlignment.left; public vAlignment verAlign = vAlignment.top; public enum UnitsIn{pixels, screen_percentage}; public UnitsIn unit = UnitsIn.pixels; public int width = 50; public int height= 50; public int xOffset = 0; public int yOffset = 0; public bool update = true; private int hsize, vsize, hloc, vloc; void Start (){ AdjustCamera (); } void Update (){ if(update) AdjustCamera (); } void AdjustCamera(){ int sw = Screen.width; int sh = Screen.height; float swPercent = sw * 0.01f; float shPercent = sh * 0.01f; float xOffPercent = xOffset * swPercent; float yOffPercent = yOffset * shPercent; int xOff; int yOff; if(unit == UnitsIn.screen_percentage){ hsize = width * (int)swPercent; vsize = height * (int)shPercent; xOff = (int)xOffPercent; yOff = (int)yOffPercent; } else { hsize = width; vsize = height; xOff = xOffset; yOff = yOffset; } switch (horAlign) { case hAlignment.left: hloc = xOff; break; case hAlignment.right: int justfiedRight = (sw - hsize); hloc = (justfiedRight - xOff); break; case hAlignment.center: float justifiedCenter = (sw * 0.5f) - (hsize * 0.5f); hloc = (int)(justifiedCenter - xOff); break; } switch (verAlign) { case vAlignment.top: int justifiedTop = sh - vsize; vloc = (justifiedTop - (yOff)); break; case vAlignment.bottom: vloc = yOff; break; case vAlignment.middle: float justifiedMiddle = (sh * 0.5f) - (vsize * 0.5f); vloc = (int)(justifiedMiddle - yOff); break; } GetComponent<Camera>().pixelRect = new Rect(hloc,vloc,hsize,vsize); } }
right
, Ver Align to top
, and Unit to pixels
. Leave XOffset and YOffset as 0
, change Width to 400
and Height to 200
, as shown here:In this example, we added a second camera in order to display the scene from a different point of view. The second camera's relative viewport was originally placed on top of the Main Camera's viewport, hence taking up all of the screen space.
The PictureInPicture
script changes the camera's Normalized Viewport Rect, thus resizing and positioning the viewport according to the user's preferences.
First, it reads user preferences for the component (dimensions, alignment, and offset for the PiP viewport) and converts dimensions in screen percentage to pixels.
Later, from the if(unit == UnitsIn.screen_percentage){
conditional, the script calculates two of the viewport Rect parameters (width and height) according to the user's selection.
Later on, to switch statements to adjust the other two viewport Rect parameters (horizontal and vertical location) according to the total screen dimensions, PiP viewport dimension, vertical/horizontal alignment, and offset.
Finally, a line of code tells the camera to change the location and dimensions of the camera's Viewport Rect:
GetComponent<Camera>().pixelRect = new Rect(hloc,vloc,hsize,vsize);
The following are some aspects of your picture-in-picture that you could change:
If you change the Unit option to screen_percentage
, the viewport size will be based on the actual screen's dimensions instead of pixels.
18.117.230.81