Creating a picture-in-picture effect

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.

Getting ready

For this recipe, we have prepared the BasicScene Unity package, containing a scene named BasicScene. The package is in the 1362_05_codes folder.

How to do it...

To create a picture-in-picture display, just follow these steps:

  1. Import the BasicScene package into your Unity Project.
  2. From the Project view, open the BasicScene level. This is a basic scene featuring an animated character and some extra geometry.
  3. Add a new Camera to the scene through the Create drop-down menu on top of the Hierarchy view (Create | Camera).
  4. Select the camera you have created and, from the Inspector view, change its Depth to 1, as shown in the following screenshot:
    How to do it...
  5. From the Project view, create a new C# Script file and rename it PictureInPicture.
  6. Open your script and replace everything with the following code:
    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);
      }
    }

    Note

    In case you haven't noticed, we are not achieving percentages by dividing numbers by 100, but rather multiplying them by 0.01. The reason behind this is that computer processors are faster at multiplying than dividing.

  7. Save your script and attach it to the camera you previously created.
  8. Uncheck the new camera's Audio Listener component and change some of the PictureInPicture parameters: change Hor Align to 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:
    How to do it...
  9. Play your scene. The new camera's viewport should be visible in the top-right corner of the screen, as shown below:
    How to do it...

How it works...

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

There's more...

The following are some aspects of your picture-in-picture that you could change:

Making the picture-in-picture proportional to the screen's size

If you change the Unit option to screen_percentage, the viewport size will be based on the actual screen's dimensions instead of pixels.

Changing the position of the picture-in-picture

The Ver Align and Hor Align options can be used to change the viewport's vertical and horizontal alignment. Use them to place it where you wish.

Preventing the picture-in-picture from updating on every frame

Leave the Update option unchecked if you don't plan to change the viewport position in running mode. Also, it's a good idea to leave it checked when testing and uncheck it once the position has been decided and set up.

See also

  • The Displaying a mini-map recipe in this chapter
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.159.187