Package Contents
The Unity plugin package contains the following:
Scripts
- Cardboard.cs - Singleton connection to the native code VR device.
- CardboardEye.cs - Applies an eye view/projection to a stereo camera.
- CardboardHead.cs - Applies the Cardboard head view to its transform.
- GazeInputModule.cs - Control uGUI elements with gaze and trigger.
- Pose3D.cs - Contains a rotation and translation.
- RadialUndistortionEffect.cs - Image Effect simulating distortion correction.
- StereoController.cs - Controls mono vs stereo rendering.
Editor Scripts
- CardboardEditor.cs - Customize parameters of the Cardboard object.
- StereoControllerEditor.cs - Adds a button to update the stereo eye cameras.
Prefabs
- CardboardMain - A drop-in replacement for a Main Camera object.
- CardboardHead - A drop-in replacement for other cameras.
- CardboardAdapter - Adds stereo rendering to an existing camera.
Shaders
- RadialUndistortionEffect - Shader for simulating distortion correction.
Demo
- DemoScene - Simple demonstration of the plugin.
Legacy
Features intended for supporting existing projects in older versions of Unity.
- CardboardGUI.cs - Capture OnGUI onto a texture.
- CardboardGUIWindow.cs - Show the OnGUI texture on a mesh in scene.
- CardboardGUIMouse.cs - Control mouse by user's gaze; draw mouse pointer.
- CardboardGUI prefab - Make it easy to show and interact with OnGUI in stereo.
- SkyboxMesh.cs - Converts a Camera's skybox to a textured mesh at runtime.
- StereoLensFlare.cs - Support directional lens flares but with parallax.
- SkyboxMesh shader - Unlit textured background.
- GUIScreen shader - Unlit textured overlay with transparency.
Scripts
This section covers the specific purpose of the individual scripts and how they work together, whether within the provided prefabs or if you add them to the scene yourself.
Cardboard.cs
Provides access to the underlying VR device, implemented in native code. There should only be one of these in a scene. An instance will be generated at runtime if needed, or you can add one via the Editor if you wish to customize its starting properties.
Types
enum Eye { Left, Right }
enum Distortion { Distorted, Undistorted }
Distorted
) or as if no lenses were present (Undistorted
).
Properties
Cardboard SDK [static, read only]
bool DistortionCorrection [default true]
bool VRModeEnabled [default true]
bool TapIsTrigger [default false]
bool EnableAlignmentMarker [default true]
bool EnableSettingsButton [default true]
float NeckModelScale [0..1, default 1]
bool AutoDriftCorrection [default true]
bool Triggered [read only]
bool Tilted [read only]
RenderTexture StereoScreen
The property is typically auto-initialized by Cardboard, but if you wish to customize the texture, you may assign to it in your code.
Pose3D HeadPose [read only]
Pose3D EyePose(Cardboard.Eye eye)
Matrix4x4 Projection(Cardboard.Eye eye, Distortion distortion [default Distorted])
CardboardEye
script takes care of adjusting the matrix for its particular camera.
Rect Viewport(Cardboard.Eye eye, Distortion distortion [default Distorted])
StereoScreen
render texture. In the Undistorted case, it refers to the actual rectangle on the screen that the eye can see.
Vector2 ComfortableViewingRange [read only, default 1-100000 meters]
Events
Action OnTrigger
Action OnTilt
Methods
void UpdateState()
Multiple invocations per frame are OK: Subsequent calls merely yield the cached results of the first call. To minimize latency, it should be first called later in the frame (for example, in LateUpdate
) if possible.
bool Recenter()
void CreateStereoScreen()
CardboardEye.cs
Renders the same view as the parent StereoController's mono camera, but for a specific stereo eye. The view and projection matrices are continuously updated from the EyeView
and Projection
properties of the Cardboard object. The render output is directed to Cardboard's StereoScreen
render texture, either to the left half or right half depending on the chosen eye.
Rendering of the CardboardEye
Camera is controlled by the StereoController and not by the normal Unity render pipeline. As such, the CardboardEye
Camera will generally have enabled
set to false.
In each frame, all camera settings (for example, culling mask, field of view, near/far clipping distances, etc) are copied from the parent mono camera before rendering. Therefore it is meaningless to set the properties on the Camera attached to the CardboardEye
itself.
Properties
Cardboard.Eye eye
EyeOffset
and Projection
matrix to use and which half of the screen to render to.
LayerMask toggleCullingMask
StereoController Controller [read only]
StereoController
that controls this eye.
CardboardHead Head [read only]
CardboardHead
.
CardboardHead.cs
Attach this script to any game object that should match the user's head motion. By default, it continuously updates the local transform to the HeadView
of the Cardboard
object. A target object may be specified to provide an alternate reference frame for the motion.
This script will typically be attached to directly to a Camera object, or to its parent if you need to offset the camera from the origin. Alternatively it can be inserted as a child of the Camera and parent of the CardboardEye
camera. Do this if you already have steering logic driving the mono Camera and wish to have the user's head motion be relative to that. Note that in the latter setup, head tracking is visible only when VR Mode is enabled.
In some cases you may need two instances of CardboardHead, referring to two different targets (one of which may be the parent), in order to split where the rotation is applied from where the positional offset is applied. Use thetrackRotation
and trackPosition
properties in this case.
Properties
bool trackRotation [default true]
bool trackPosition [default true]
Transform target [default null]
bool updateEarly [default false]
LateUpdate()
or Update()
. The default isLateUpdate()
to reduce latency. However, some scripts need to use the camera's direction to affect the game play, e.g by casting rays or steering a vehicle, during the LateUpdate()
phase.
This can cause an annoying jitter because Unity, during this LateUpdate()
phase, will update the head object first on some frames but second on others. If this is the case for your game, try switching the head to use Update()
.
Ray Gaze [read only]
GazeInputModule.cs
This script provides an implemention of Unity's BaseInputModule
class, so that Canvas-based UI elements (uGUI) can be selected by looking at them and pulling the trigger or touching the screen. See the Guide for details concerning use.
GazeInputModule
emits the following events: Enter, Exit, Down, Up, Click, Select, Deselect, and UpdateSelected. Scroll, drag and drop, move, and submit/cancel events are not emitted.
Properties
bool vrModeOnly [default false]
true
), or all of the time (false
). Set to false if you plan to use direct screen taps or other input when not in VR Mode.
GameObject cursor [default null]
float clickTime [default 0.1]
Vector2 hotspot [default (0.5, 0.5)]
Canvas
' event camera.
Pose3D.cs
Encapsulates a rotation and a translation. This is a convenience class that allows construction and value access either by Matrix4x4 or Quaternion+Vector3 types.
Vector3 Position
Quaternion Orientation
Matrix4x4 Matrix
Matrix4x4 RightHandedMatrix
RadialUndistortionEffect.cs
Implements the same barrel distortion that is performed by the native code. It is used to show the effect of distortion correction when playing the scene in the Editor, and as the fall back when the native code distortion is not available or disabled.
StereoController.cs
This script must be added to any camera that should render stereo when the app is in VR Mode. This includes picture-in-picture windows, whether their contents are in stereo or not: the window itself must be twinned for stereo, regardless.
For each frame, StereoController
decides whether to render via the camera it is attached to (the mono camera) or the stereo eyes that it controls (see CardboardEye
). You control this decision for all cameras at once by setting the value of Cardboard.SDK.VRModeEnabled
.
For technical reasons, the mono camera remains enabled for the initial portion of the frame. It is disabled only when rendering begins in OnPreCull()
, and is reenabled again at the end of the frame. This allows 3rd party scripts that useCamera.main
, for example, to refer the the mono camera even when VR Mode is enabled.
At startup the script ensures it has a full stereo rig, which consists of two child cameras with CardboardEye
scripts attached, and a CardboardHead
script somewhere in the hierarchy of parents and children for head tracking. The rig is created if necessary, the CardboardHead
being attached to the controller itself. The child camera settings are then cloned or updated from the mono camera.
It is permissible for a StereoController
to contain another StereoController as a child. In this case, aCardboardEye
is controlled by its closest StereoController
parent.
The Inspector panel for this script includes a button Update Stereo Cameras. This performs the same action as described above for startup, but in the Editor. Use this to generate the rig if you intend to customize it. This action is also available via Component -> Cardboard -> Update Stereo Cameras in the Editor’s main menu, and in the context menu for theCamera
component.
Properties
bool directRender [default true]
float stereoMultiplier [0..1, default 1]
CardboardHead
object for that. Instead, it is a control of the eye vergence, that is, how cross-eyed the stereo rig is. Set to 0 to turn off stereo in this rig independently of any others.
float matchMonoFOV [0..1, default 0]
This value determines how much to match the mono camera's field of view. This is a fraction: 0 means no matching, 1 means full matching, and values in between are compromises. Reasons for not matching 100% would include preserving some VR-ness, and that due to the lens distortion the edges of the view are not as easily seen as when the phone is not in VR-mode.
Another use for this variable is to preserve scene composition against differences in the optical FOV of various Cardboard models. In all cases, this value simply lets the mono camera have some control over the scene in VR mode, like it does in non-VR mode.
float matchByZoom [0..1, default 0]
It is not recommended to use simple zooming for typical scene composition, as it conflicts with the VR need to match the user's head motion with the corresponding scene motion. This should be reserved for special effects such as when the player views the scene through a telescope or other magnifier (and thus the player knows that VR is going to be affected), or similar situations.
Note that matching by moving the eyes requires that the centerOfInterest object be non-null, or there will be no effect.
Transform centerOfInterest [default null]
The FOV adjustment is done by moving the eyes toward or away from the COI so that it appears to have the same size on screen as it would in the mono camera. This is disabled if the COI is null.
float radiusOfInterest [default 0]
centerOfInterest
is generally meant to be just a point in space, like a 3D cursor. Occasionally, you will want it to be an actual object with a definite size. Set this property to the approximate radius of the object to help the FOV-matching code compensate for the object's horizon.
bool checkStereoComfort [default true]
centerOfInterest
is between the min and max comfortable viewing distances (see Cardboard
), or else it adjusts the stereo multiplier to compensate. If the centerOfInterest
has a nonzeroradiusOfInterest
, then the near side is checked. The centerOfInterest
must be non-null for this setting to have any effect.
float screenParallax [0..1, default 0]
float stereoPaddingX [0..1, default 0]
float stereoPaddingY [0..1, default 0]
CardboardHead Head [read only]
CardboardHead
that affects the stereo cameras of this controller.
CardboardEye[] Eyes [read only]
InvalidateEyes()
if it is ever necessary to reset the cache.
RenderTexture StereoScreen [read only]
Cardboard.SDK.StereoScreen
.
Methods
void InvalidateEyes()
Eyes
array. Call this function only if you change which active game objects have CardboardEye
components controlled by this StereoController.
Editor Scripts
The following scripts customize the Inspector panels for some Cardboard components.
CardboardEditor.cs
A custom editor for properties on the Cardboard
script. This appears in the Inspector window of a Cardboard object. Its purpose is to allow changing the Cardboard.SDK
object's properties from their default values. In particular, theInCardboard
property's value can be set while playing in the Editor in order to fake the phone being inserted into or removed from a Cardboard.
StereoControllerEditor.cs
A custom editor for the StereoController
script. It exists to add the Update Stereo Cameras button to theStereoController
's Inspector window, and to the corresponding main menu entry and Camera context menu command. The usage of the these actions is described in the StereoController.cs
section above.
Prefabs
This section describes the prefabs that are provided by the package.
CardboardMain
This prefab is intended to be a drop-in replacement for a normal Unity camera, such as Main Camera, primarily when the camera is simple, i.e. not already festooned with scripts. A brand new Unity project is a good time to use it. To apply it in the Editor, delete the camera in question and replace it with an instance of this prefab.
The prefab contains a top-level object called CardboardMain, which has a Cardboard script attached to it for controlling VR Mode settings. Under this is the Head object, which has a CardboardHead attached for tracking the user's head motion. That in turn has a Main Camera child object, with the StereoController
script attached. This camera is tagged as a MainCamera so that the Unity property Camera.main
will find it. Finally there are the Left and Right stereo eye cameras at the bottom of the hierarchy.
CardboardHead
This prefab is a replacement for other cameras in the scene that also need head-tracking. It has a top-level object calledHead with a CardboardHead
script. Under that is the Camera child which has the StereoController
script, and then the Left and Right stereo eye cameras. Unlike CardboardMain, the camera in this prefab is not tagged MainCamera.
CardboardAdapter
This prefab is for when you wish to keep your existing Camera object, usually because it is heavily wired with game logic and already moves exactly as needed for non-VR game play. Place this prefab as a child of the camera, and then executeUpdate Stereo Cameras (or manually attach StereoController
to the camera) to complete the rig.
Unlike the other prefabs, this setup places the head-tracked node below the Main Camera. Therefore, only the stereo cameras are affected by the user's head motion.
General Prefab Notes
Each prefab is provided as a starting point for customization. It is a framework on which to attach additional scripts for your own needs. Elements under a Head node will maintain a fixed position on screen, thus acting like a Heads-up Display (HUD). Elements that are siblings of Head will maintain a fixed position and orientation relative to the overall point of view, thus acting more like a cockpit instrument panel.
Legacy Reference
Scripts
This section describes scripts provided for legacy purposes.
CardboardGUI.cs
Captures Unity's OnGUI pass in a texture which can then be rendered onto a mesh, such as a quad, in the scene (seeCardboardGUIWindow
below).
Position the GUI mesh in 3D space using the gameobject's transform. Note: do not place the object as a child of the CardboardHead, or the user will not be able to look at different parts of the UI because it will move with them. It is better to place it as a sibling of the Head object.
Properties
delegate void OnGUICallback()
OnGUI()
method.
event OnGUICallback onGUICallback [static]
OnGUI()
calls that will be captured in the texture. Add your script's OnGUI method to enable the script's GUI in the CardboardGUI
window. See the Code Changes section just below for details.
bool IsGUIVisible [static, default false]
CardboardGUI
shows anything in the scene. Set it to true to allow the GUI to draw, and false to hide it. The purpose is so you can move GUI elements away from the edges of the screen (which are hard to see in VR Mode), and instead pop up the GUI when it is needed, and dismiss it when not.
bool Triggered [static, read only]
Cardboard.SDK.Triggered
that hides the trigger event when the GUI is visible (i.e. when you setIsGUIVisible
to true). By using this flag in your scripts rather than the Cardboard.SDK
's triggered flag, you allow the GUI to take the trigger events when it is visible. This is when the trigger is needed for clicking buttons. When the GUI is hidden, the trigger events pass through.
Color Background [default transparent]
Methods
bool OKToDraw(MonoBehavior mb) [static]
onGUICallback
event). Add a check at the top of OnGUI()
and exit early if it is false. See the Code Changes section just below for details.
Code Changes to Scripts using OnGUI()
Some minor changes must be made to any script that uses OnGUI() in order to work with CardboardGUI. These are non-invasive and do not alter the behavior of the script when the app is not in VR Mode. The changes are as follows:
void Start() {
CardboardGUI.onGUICallback += this.OnGUI;
// ...
}
void OnDestroy() {
CardboardGUI.onGUICallback -= this.OnGUI;
// ...
}
void OnGUI() {
if (!CardboardGUI.OKToDraw(this)) return;
// ...
}
CardboardGUIMouse.cs
Attach this script to the same object as CardboardGUI
itself. It can draw a cursor image into the GUI texture to show the location of the mouse pointer. It supports moving the mouse with the user's gaze, and clicking on the UI with the trigger, but other mouse-controlling devices, such as gamepads, will work as well.
Properties
CardboardHead Head [default null]
CardboardHead
instance that will provide the user's head tracking for gaze-based mouse control. Leave it null if you are using another pointing device.
Texture PointerImage [default null]
Vector2 PointerSize [default (0,0)]
Texture PointerSpot [default (0,0)]
CardboardGUIWindow.cs
Draws all or part of the GUI texture captured by CardboardGUI
. It must be attached on a child gameobject of theCardboardGUI
, accompanied by a MeshFilter
, a MeshRenderer
, and Collider
components. The mesh will be used to draw the texture, and the collider used to check for intersections with the user's gaze for mouse positioning. The material used for rendering the texture is created and maintained internally by this script.
Each instance can pick out a different region of the GUI texture to show (see Rect
below). Use the object's transform to position and orient this region in space relative to the parent CardboardGUI
object. The mesh is automatically scaled to account for the aspect ratio of the overall GUI.
By using multiple CardboardGUIWindow
children of the CardboardGUI
object, you can build a VR Mode GUI layout that is arranged in space around the user. This layout is independent of the normal OnGUI layout when the app is not in VR Mode. The enabled
flag on individual CardboardGUIWindows can be used to turn on or off the separate regions of the GUI.
Properties
Rect Rect [default (0,0,1,1)]
CardboardGUI
texture to draw on the attached mesh. The units are exactly the same as a Camera component's Viewport Rect
: (0,0)
is the bottom left corner and (1,1)
the top right. Use it to pick out the region of the GUI to draw on this mesh.
SkyboxMesh.cs
Unity 4's built-in skybox backgrounds do not work correctly for stereo rendering. Since the same exact image is rendered to each eye, the background has zero parallax. Given the optics of Cardboard, this yields an effective stereo depth that is likely right in the middle, or worse, front of the scene. The results in a visually painful parallax clash with other objects in the scene.
This script should be attached to the Camera which represents the primary viewpoint of the player (such as Main Camera). At runtime it builds a mesh that will be textured with the camera's skybox material. The mesh is scaled up to just fit inside the far clipping plane, and kept centered on the camera's position.
Types
enum Shape { Sphere, Cube }
Properties
Shape shape [default Sphere]
shape
simply determines whether those sides are convex or flat.
int segments [default 32]
segments
.
int layer [default 0]
StereoLensFlare.cs
Unity 4's built-in lens flares do not work correctly for stereo rendering when in Directional mode, for similar reasons as the skybox mentioned previously. This script can be attached to a Lens Flare to make it stereo-aware directional.
To use it, add the script to a Lens Flare and clear the flare's Directional flag so that the flare is actually positional. This script keeps the flare at a distance well away from the mono camera along the flare's own forward vector, thus recreating the directional behavior, but with proper stereo parallax. The flare is repositioned relative to each camera that renders it.
Properties
float range [0..1, default 0.75]
Prefabs
This section describes the prefabs that are provided by the package for legacy purposes.
CardboardGUI
This prefab captures the OnGUI pass of a frame into a texture. It draws the texture on a quad in the scene, along with cursor image for the mouse pointer, if you specify one. It can move the mouse by tracking the user's gaze and it can read the trigger to "click" UI elements.
To use it, add an instance of the prefab to the scene. It should not be placed under a CardboardHead
if you want the user's gaze to control the mouse, but can be if you use an alternative input device. The prefab contains one child called GUIScreen, which by default draws the entire screen's OnGUI layer on a single quad.
It is possible to add more such children to the CardboardGUI object. Just duplicate the GUIScreen
child in the Editor as needed, adjust each child's Rect to pick out a different region of the OnGUI layer, and set its Transform to place that region in the scene. In this way you can completely rearrange the GUI layout when in VR Mode without changing anyOnGUI()
functions' code or behavior.
CardboardGUI
and its Window children have visibility controls that you can use to convert a non-transient (i.e. always on) UI to a transient (popup) UI when in VR Mode. Non-transient UI is usually placed along the edges of the screen, which in HMD stereo systems are extremely hard to see. For VR Mode, you will likely need to rearrange the UI to appear front-and-center, perhaps depending on which way the user looks. This obscures the scene itself, unless the UI can be hidden when not needed.