2.1 Hello Cube Interactions
This topic covers the basics of user input with MagicScript Components in your Magic Leap app. In it you'll add another component, a Toggle, to the Hello Cube example and make the MagicScript cube rotate when the toggle is on.
Pre-requisites
Before starting this tutorial, you should complete Hello, Cube! MagicScript.
Add Rotation
The three-dimensional rotation properties in MagicScript Components are represented as quaternions, which are compact, simple, and convenient for axis-angle representations in homogeneous coordinates. Simply, quaternions are determined from the angle about a unit axis and are represented as [x, y, z, w]. See Quaternions and spatial rotation for more information.
Euler angles are an easy way to specify rotations around specific axes and are commonly referred to as yaw (around z-axis), pitch (around y-axis), and roll (around x-axis). In this example, we recommend using Euler angles to create the rotation angles and then convert them to unit quaternions to update the rotation property on the Model component. A conversion function is provided for you in the steps below. See Conversion between quaternions and Euler angles for more information. Important: The coordinate system in MagicScript is y down and +z forward.
Now that you have the basics of rotation in three-dimensions, let's make a cube rotate around the y-axis.
- In the helloCube/src/app.js file from the Hello, Cube! example, add a rotation quaternion variable for the Cube to the app state and initialize it with [0, 0 ,0 ,0] in the constructor. A constructor is a special function that creates and initializes an instance of the class. With React, the constructor is the only place where you should assign this.state directly for a component. For updating the app state anywhere else, call this.setState, which calls the render function for you and updates the app.
- Add the local rotation property to the Cube tag and connect it to the app state's rotation, this.state.rotation.
- Create a method to make an object rotate around its y-axis using the current timestamp from Date.now() as the angle for rotation.
- Set up a timer to update the cube's rotation every 10 milliseconds. The timer starts when the component is rendered for the first time (mounted in React terms), and the timer is cleaned up when the component is removed (unmounted).
- Build and run the app to verify that the cube starts rotating on app start. Connect a Magic Leap device to your computer via USB. Open a command-line session from The Lab. In the command line session, navigate to the helloCube app project folder and enter: magic-script build -i. Launch the Hello, Cube! app on the device. To view the app using the Simulator without a device, see Zero Iteration MagicScript.
Add Toggle Component
Since MagicScript Components are built on Lumin Runtime and UIKit, user interactions with the Control work inherently with the user interface elements provided by MagicScript Components. Simply declaring the component tag creates a user interface element that responds to the Control. To add a response to the user's actions, connect functions to the component's events.
Let's add a Toggle component to the app and see how interactions work in MagicScript Components by making the cube rotate only when the toggle is on.
- Import the Toggle component from magic-script-components by updating the import statement at the top of the app.js file to be:
- Add the Toggle tag to the render method. Verify the Toggle element appears below the cube after building and running the app. Use the Control to turn the toggle on and off.
- Add an animate boolean to the app state to track whether the cube should be currently animating or not.
- Add a check in updateRotation so the cube only rotates if animate is true.
- Add a method to toggle the animate boolean to provide a reaction to user input and connect it to the OnToggleChanged property in the Toggle component.
- Build and run the app. Verify the cube rotates when you turn the toggle on and stops rotating when the toggle is off.
Complete App
The complete app.js file looks like the following: