Make 3D Objects Move with View in Magic Leap and Unity

By default your objects will stay in a fixed position in the Magic Leap Simulator. This guide will go through how to make your objects stay in view when the user looks around. (using Lumin SDK 0.13.0).

1. Prerequisites

To get started make sure you’ve completed the Magic Leap Hello, Cube tutorial as this tutorial will follow on from that.

You should have a cube in your virtual room in the Magic Leap Simulator.

Currently in Lumin SDK the “headpose” is represented by the main camera. To account for the wearers height the y position is automatically set to 2 in the simulator.

2. Getting the “Headpose”

Create new script on the cube called stickyObject.

Open the script to edit it.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StickyObject : MonoBehaviour 
{
    private Camera _camera;

    // Use this for initialization
    void Start () 
    {
        _camera = Camera.main;
        if(_camera == null)
        {
            Debug.Log("Failed to get headpose");
            return;
        }
    }
    
    // Update is called once per frame
    void Update () {}
}

Line 7: creates a variable to hold the main camera.

Line 12: assigns the camera variable to the main camera.

Line 13 – 17: check that the camera has been assigned, if it hasn’t output an error message to the log and return.

3. Setup Offsets

Next we need to create some offsets so that we can maintain the objects orientation in the view when it moves.

public class StickyObject : MonoBehaviour 
{
    private Camera _camera;
    //hold the objects initial orientation
    private Vector3 objectOrientationInCamera;
    private Quaternion objectRotationOffset;

    // Use this for initialization
    void Start () 
    {
        _camera = Camera.main;
        if(_camera == null)
        {
            Debug.Log("Failed to get headpose");
            return;
        }
        //get the initial offsets for the object
        objectOrientationInCamera = transform.position;
        objectRotationOffset = transform.rotation;

        //adjust the y position to account for the y2 startpos of the camera
        objectOrientationInCamera.y -= 2;
    }
    
    // Update is called once per frame
    void Update () {}
}

Line 5 & 6: create two variables, a vector3 to hold the starting position of the object and a quaternion to hold the starting rotation.

Line 18 & 19: initialise the two variables to the objects starting position and starting rotation.

Line 22: The y pos of the camera is automatically set to 2 when running in the simulator. Since we’re using the camera positioning to reposition the object we need to subtract 2 from the y pos of the object.

4. Update the Objects Position

Finally let’s do the math to update the position and rotation of the object when the headpose changes.  We’re going to use Slerp and SlerpUnclamped so that the object movement looks smooth.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StickyObject : MonoBehaviour 
{
    private Camera _camera;
    //hold the objects initial orientation
    private Vector3 objectOrientationInCamera;
    private Quaternion objectRotationOffset;

    // Use this for initialization
    void Start () 
    {
        _camera = Camera.main;
        if(_camera == null)
        {
            Debug.Log("Failed to get headpose");
            return;
        }
        //get the initial offsets for the object
        objectOrientationInCamera = transform.position;
        objectRotationOffset = transform.rotation;

        //adjust the y position to account for the y2 startpos of the camera
        objectOrientationInCamera.y -= 2;
    }
    
    // Update is called once per frame
    void Update () 
    {
        //update the position of the object
        Vector3 posTo = _camera.transform.position + (_camera.transform.forward);
        posTo += objectOrientationInCamera;
        transform.position = Vector3.SlerpUnclamped(transform.position, posTo, Time.deltaTime * 5f);

        //update the rotation of the object
        Quaternion rotTo = Quaternion.LookRotation(transform.position - _camera.transform.position) * objectRotationOffset;
        transform.rotation = Quaternion.Slerp(transform.rotation, rotTo, Time.deltaTime * 5f);
    }
}

Line 33: set the speed for the object to move.

Line 34: calculate the new position for the object using the cameras current position, the cameras forward value and the offset.

Line 35: update the position of the object using the SlerpUnclamped function to animate the movement.

Line 39: set the speed for the object to rotate.

Line 40: calculate the new rotation for the object using the objects current position, the cameras current position and the rotation offset.

Line 41: update the rotation of the object using the Slerp function to animate the rotation.

5. Play!

When you hit play the cube should be directly in front of you, as you move around the room and look around the cube should move with the view.

Cube Sticking to the View in Magic Leap Simulator with Unity

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.