How to Make Interactable Tectonic Plates in AR – Part 2

How to Make Interactable Tectonic Plates in AR – Part 2

If you haven’t read Part 1 of the tutorial yet, it’s highly recommended you do so.

In the first part of our tutorial, we began setting up our tectonic plates with animations and so forth.  We’re ready to continue with our educational AR app and set it up so that the correct animation can run at the right time.

Continuing with Scripting the Touch Manager

Now it’s time to create the “CalculateDragDirectionOnPlate” function. It takes in a touch end position in pixel coordinates. This is a pretty big function, so let’s take it in steps.

First, we make a variable which will hold the world position of the touch. Then we create a new ray which shoots from the screen to the touch position.

This is unlike the normal raycast though. Instead of shooting a ray and checking if it hit a collider, we’re doing a plane raycast. This creates an abstract, flat plane which we then get the position that the ray intersected it. That’s our world position.

We now need to check the distance of the drag. If it’s too short, then we’ll un-assign the plate (we’ll make this later) and return.

Then, we need to calculate a normalized direction between the two positions. Next, we round the X and Z values to the nearest integer. This means that each axis will be either: -1, 0 or 1. With this, we can then calculate the direction of the drag in 4 ways.

Now we check for a right, left, forwards or back drag by looking at the axis direction.

Then we’ll assign that direction to the plate.

Let’s make that script now.

Scripting the Plate Manager

Create a new C# script called “PlateManager” and attach it to the “Manager” object.

We need to add a few libraries, for using the timelines.

Now let’s start on our variables.

First, we got our left and right plates which hold all the data for their corresponding plates. “currentlyAnimating” is a bool which is true when we’re animating the plates.

Then we need to list all the playable assets (timelines) for each of our animations.

We need to also access the playable director, so let’s link it.

Finally, we create an instance (singleton) of the script so that we can access it easier later on.

Our first function is our largest and most important. “AssignPlateMovement” is a function which is called from the TouchManager. It sends over the plate to assign and a global movement direction.

First, we check if we’re currently animating. If so, we can’t assign anything so return. Then we check if this is the left plate we’re setting. Since the left plate is a rotated version of the right one, we need to flip the X axis of the move direction.

Now we check the direction and assign the corresponding movement to the plate.

If you’re converging the plates, the one on top depends on the last plate you drag. So we need to check if the other plate’s assigned movement is convergent under. If so, then the current one is over. Otherwise, we just set it to converge under.

Now we need to activate the arrow and rotate it to face the direction we dragged.

If we have an assigned movement on both plates, we check to see if the plates are compatible. If so, we call the “PlayAnimation” function, otherwise we call the “OnAnimationEnd” function.

That’s 3 functions right there that we haven’t made yet. Let’s start with “PlatesAreCompatible”.

This returns a bool. True being that the plates are compatible and false being that they aren’t.

It’s basically checking for all the possible plate combinations.

Now let’s create a function called “UnassignPlate”. This basically resets a plate’s assigned movement and disables the arrow visual.

“OnAnimationEnd” is a function that will be called after the animation has finished. This basically resets the plates. When the animation begins, this function gets invoked to be called after [timeline duration] seconds.

Now let’s create the “PlayAnimation” function.

First, we deactivate the arrow visuals.

Then we set the corresponding timeline to the director.

Lastly, we play the animation and invoke “OnAnimationEnd” to be called in [timeline duration] seconds.

The last function we call is “DoubleTapResetPlates”. This just resets everything when you double tap.

Lava Visual

Something that adds to the visual element is a lava element.

Create a new Plane object (right click Hierarchy > 3D Object > Plane) and call it “Lava”. Set the material to “Lava”. Then, scale and position it so it leaks around the edges and just rises above the base. Finally, set it as a child of the “TectonicPlates” object.

Lava object in Unity with Transform component highlighted

We’re also going to add a slight animation which will “pulse” the intensity of the lava.

First, un-parent the lava object so it’s got no parent. We need to do this due to the original parent already having an animator component.

So, with the lava selected, go to the Animation window and create a new animation.

Here, I ping-ponged the scale and color.

Lava object animation demonstration in Unity

Once you’ve finished animating, you can make the “Lava” object a child of the “TectonicPlates” object.

Creating the UI Element

Since this app is aimed at education, it would be good to show the user what type of plate movement they just triggered.

Create a new Canvas (right click Hierarchy > UI > Canvas). Set the “Render Mode” to World Space. Set the scale to 0.015, and position it behind the plates.

Unity Canvas UI object added to scene

Add a new Text element to the canvas (right click Canvas > UI > Text). Resize it and edit the Text component to your liking. I added an Outline component to contrast any possible background.

Unity canvas with tectonic plate text object added

Now create an animation called “InfoText_Entrance” that makes the text pop up and after a few seconds it disappears.

Unity animation for UI text element

With the animation completed, let’s disable the text object and begin scripting.

Create a new C# script called “UI” and attach it to the “Manager” object.

Since we’re going to be using UI, we’ll need to reference Unity’s UI library.

Our 2 variables are the “infoText”, which is the actual text element we’re going to edit, and “infoTextAnim” is the Animator component attached to the text.

We’re also going to include an instance (singleton) so that we can access this script easier later on.

Our one and only function is “SetText”. This sets the text to display a certain string and plays the animation.

Connecting the Scripts

Now that we have all of our scripts, it’s time to connect them together.

First, let’s start with the TouchManager script.

Create a new function called “DoubleTapCheck”. This checks to see if the user has double tapped, and calls the corresponding function in the PlateManager script if so.

We also need to call this function up in Update, where we check…

Then, in the “CalculateDragDirectionOnPlate” function, we need to do 2 things.

First, where we check if the player tapped and didn’t drag, call the “UnassignPlate” function in the PlateManager script.

And right at the end of the function, assign the plate movement.

Now for the PlateManager script.

In the “PlayAnimation” function, we need to call the “SetText” function in UI to display the current animation playing.

Finally, in the “DoubleTapResetPlates” function, we need to deactivate the text object.

Connecting Inspector Properties

Make sure that each plate’s “Plate” script has the correct properties assigned to it.

Unity Plate script with object assignment

Do the same for the “Manager” object and its various scripts.

Plate Manager script in Unity with objects assigned

Testing in the Editor

You might want to test out the app in the editor before we build it to a device. There are three things we need to do:

  • Add mouse input
  • Disable EasyAR integration
  • Add a camera to the scene

To add mouse input, go to the “TouchManager” script. In the “Update” function, add:

Back in the editor we need to disable the EasyAR components, so that they don’t try and run. Deactivate the “EasyAR_Startup” GameObject, and disable the Image Target Behaviour script on the “ImageTarget_TectonicPlate” GameObject.

Unity with AR related functions deactivated

Now we just need to add a new camera to the scene (right click Hierarchy > Camera). Set its tag as “MainCamera” and position it where you like.

Unity Camera object as seen in Hierarchy and Inspector

You should now be able to press play and test the app out in the editor!

Unity tectonic plates app in action

Building

You can follow the last section of this tutorial on how to build to an Android device.

Conclusion

So we’ve made a working model of tectonic plates, with interactions to trigger certain plate interactions. If you want to use this in AR, you’ll need to print out the included image marker (located inside the StreamingAssets) folder.  You can locate the project files here.