Introduction

Over the past year or so, Unity has become a popular tool for creating AR apps as it makes things relatively simple for developers to get things up-and-running. One obstacle, however, is that many developers aren’t exactly experts at 3D modeling and purchasing assets can be very expensive. Google set out to fix this problem by creating Poly, which is an API for accessing and managing 3D models designed for AR and VR apps. The best part of all is that Poly has its own Unity plugin and a developer can go from zero modeling experience to having a full game populated with assets in a few short clicks. If you are a game developer who is fine at scripting but never actually gets past the “placeholder cubes” phase of your project, Poly is exactly the type of tool that you need for your next game.

The Poly toolkit for Unity has a large library of assets that you can use in your AR or VR projects. You can also upload your own assets to share or to use privately. Poly also has a REST API for dynamically loading in assets at runtime, which opens up a whole world of possibilities when it comes to making games.

Don't miss out! Offer ends in Access all 200+ courses

Access all 200+ courses New courses added monthly

New courses added monthly Cancel anytime

Cancel anytime Certificates of completion ACCESS NOW

Getting Poly and Setting Up A New Unity Project

First, before we get started with Poly in our AR app, we have to download the plugin. Next, let’s create a new Unity project. I am using Vuforia for my AR Camera, and if you do not have it installed, I’d recommend checking out this tutorial first. Using an AR camera isn’t absolutely necessary to use Poly, but all of the 3D assets were designed with AR and VR projects in mind.

In order for the Poly plugin to work properly in Unity, we have to allow “unsafe code” by going to File > Build Settings > Other Settings and ticking the box.

Now let’s go to Assets > Import Package > Custom Package and import the .unitypackage file that we just downloaded. After the package installs, the Poly window should open and we are good to go. Now we can use the Poly API in our Unity Project! If you are just interested in manually importing 3D models into your Unity game, this is all you need. You can access the Poly library by clicking Poly > Browse Assets in your Unity menu. An account or an API key is not required to use Poly for manually selecting 3D models and importing them into your Unity project, just make sure you give proper credit to the model creators in accordance to the CC-BY licence.

Importing Assets at Edit Time

The Poly plugin comes with a nice GUI library to look through. Let’s add a cheeseburger into our view by searching for “burger” and importing it into our project. You will see that Poly’s library contains both assets made by google and assets made by other Poly users.. You can upload your own assets to Poly to share with other developers or to use privately in your own project.

Poly even makes attributing the 3D model artists easy by generating an attributions file. Let’s go to Poly > Update Attributions File and in our assets folder we should be able to find our Attributions.txt file with the proper CC-BY attribution for our cheeseburger.

Importing Assets at Run Time

One of the coolest features of Poly is that we have the ability to load assets dynamically during runtime with simple API requests. This can make a huge difference in how much resources your game uses. This also makes changing assets as easy as changing a line of code, rather than importing new 3D models to your Unity project.

Let’s try and import a new assets during our game’s runtime using the Poly API.

To do this we will first need to get an API key. Let’s head over to the Google Developer Console if you don’t have one already, create a google account and also create a new project for our Unity app. Once created, click on the “Create Credentials” button in the dashboard to get an API key.

Next, we need to paste our API key into the Poly Runtime settings by going to Poly > Poly Toolkit Settings > Runtime. For making requests to the Poly asset library, we only need to create an API key. If you are interested in uploading and accessing private assets, then you will need to create an Oauth Client ID and Client Secret to receive the appropriate tokens.

Now that we have our API key in our project, we can use the Poly toolkit. Another thing we will need to do is enable the Poly Toolkit by going to Assets/PolyToolkit/Prefabs and adding it to our scene. In order to make API requests and load assets at runtime we will need this in every scene that uses Poly.

Now that we are all set to make an API request, let’s start as simple as possible by making a request for one specific 3D model. Open up the Poly window and search for the donut in the Poly API asset library. When you select the model you will see an import location, this location contains the model’s unique ID. This is what we will use for our request.

Let’s create a basic script to make the request to the Poly API using the model’s ID. Create a new C# script by right clicking in the Unity asset browser. For this tutorial I have created a script called loadNewAsset.cs and attached it to my scene as a component.

Inside the loadNewAsset.cs file, let’s create a new request using the donut model’s ID. Make sure to include ‘using PolyToolkit;’ before the class is created. We will pass in the ID as a string. For now we are just going to use the default options for our import.

using System.Collections; using System.Collections.Generic; using UnityEngine; using PolyToolkit; public class loadNewAsset : MonoBehaviour { void Start() { PolyToolkit.PolyApi.GetAsset("assets/5ApDrJhdXcG", // ← id result => { PolyApi.Import(result.Value, PolyImportOptions.Default()); }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 using System . Collections ; using System . Collections . Generic ; using UnityEngine ; using PolyToolkit ; public class loadNewAsset : MonoBehaviour { void Start ( ) { PolyToolkit . PolyApi . GetAsset ( "assets/5ApDrJhdXcG" , // ← id result = > { PolyApi . Import ( result . Value , PolyImportOptions . Default ( ) ) ; } ) ; } }

We should see a delicious-looking sprinkled donut on our screen. If you don’t see it, make sure that you have the PolyToolkit prefab added to your scene and also make sure that your C# script containing the request is included in the scene as well. Since we didn’t actually store our donut anywhere after the request, it will disappear once we stop running the scene and trigger some console warnings, but as you can see, an asset can be loaded into our scene with just a couple of lines of code!

What if we don’t want to go through the trouble of grabbing the ID manually? Well, with the Poly API we can simply make a query to search the asset library for us! Let’s go ahead and change our code so that we can make a request for frosted donuts and import the first three results.

using System.Collections; using System.Collections.Generic; using UnityEngine; using PolyToolkit; public class loadNewAsset : MonoBehaviour { public int assetCount = 0; void Start() { // Create a new request PolyListAssetsRequest req = new PolyListAssetsRequest(); // Search by keywords req.keywords = "frosted donut"; // Make the request with a callback function PolyApi.ListAssets(req, GetDonuts); } private void GetDonuts(PolyStatusOr<PolyListAssetsResult> result) { // Set options for import so the assets aren't crazy sizes PolyImportOptions options = PolyImportOptions.Default(); options.rescalingMode = PolyImportOptions.RescalingMode.FIT; options.desiredSize = 2.0f; options.recenter = true; // List our assets List<PolyAsset> assetsInUse = new List<PolyAsset>(); // Loop through the list and display the first 3 for (int i = 0; i < Mathf.Min(3, result.Value.assets.Count); i++) { // Import our assets into the scene with the ImportDonuts function PolyApi.Import(result.Value.assets[i], options, ImportDonuts); assetsInUse.Add(result.Value.assets[i]); } } private void ImportDonuts(PolyAsset asset, PolyStatusOr<PolyImportResult> result) { assetCount++; // Line the assets up so they don't overlap result.Value.gameObject.transform.position = new Vector3(assetCount * 2.5f, 0f, 0f); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 using System . Collections ; using System . Collections . Generic ; using UnityEngine ; using PolyToolkit ; public class loadNewAsset : MonoBehaviour { public int assetCount = 0 ; void Start ( ) { // Create a new request PolyListAssetsRequest req = new PolyListAssetsRequest ( ) ; // Search by keywords req . keywords = "frosted donut" ; // Make the request with a callback function PolyApi . ListAssets ( req , GetDonuts ) ; } private void GetDonuts ( PolyStatusOr < PolyListAssetsResult > result ) { // Set options for import so the assets aren't crazy sizes PolyImportOptions options = PolyImportOptions . Default ( ) ; options . rescalingMode = PolyImportOptions . RescalingMode . FIT ; options . desiredSize = 2.0f ; options . recenter = true ; // List our assets List < PolyAsset > assetsInUse = new List < PolyAsset > ( ) ; // Loop through the list and display the first 3 for ( int i = 0 ; i < Mathf . Min ( 3 , result . Value . assets . Count ) ; i ++ ) { // Import our assets into the scene with the ImportDonuts function PolyApi . Import ( result . Value . assets [ i ] , options , ImportDonuts ) ; assetsInUse . Add ( result . Value . assets [ i ] ) ; } } private void ImportDonuts ( PolyAsset asset , PolyStatusOr < PolyImportResult > result ) { assetCount ++ ; // Line the assets up so they don't overlap result . Value . gameObject . transform . position = new Vector3 ( assetCount * 2.5f , 0f , 0f ) ; } }

As you can see, we have used import options to make sure that the assets load a certain way. In our code we specified the desired size and position we wanted our assets to load in with. There are more options for filtering results, if you want to be very specific or if you want to limit your assets to a lower or higher polygon count. You can also narrow it down by featured results to ensure that you get relevant models from your request.

Attributions

The CC-BY license requires that proper attribution is given to the original creator and Poly makes this simple by providing both a manual way to generate imported assets and a method for getting the information from the API if you are loading assets dynamically.

To manually update the attributions, simply go to Poly > Update Attributions as mentioned earlier and it will generate a .txt file for you. This is ideal for users who are importing assets from Poly at edit time, and not during the game’s runtime.

To update the attributions during our AR app’s runtime, we can use the information given to us by the API when we make the request.

Let’s go ahead and modify our app to display text on the screen and then update our code to get the attribution info for all of the assets that are importing from the API request. First, add a canvas element to the scene. Next, add some text to the canvas and call it “AttributionsText”. We will leave this blank, as it will be populated by the information provided by our request when the game is run.

Let’s anchor it to the side of our screen and make it big enough to display all of the info, you may need to make the font size smaller or a different color so you can read.

Now let’s update our code to add the AttributionText object to our display.

public class loadNewAsset : MonoBehaviour { public int assetCount = 0; // Reference the text element public Text attributionsText; void Start() { PolyListAssetsRequest req = new PolyListAssetsRequest(); req.keywords = "frosted donut"; req.pageSize = 10; PolyApi.ListAssets(req, GetDonuts); } private void GetDonuts(PolyStatusOr<PolyListAssetsResult> result) { PolyImportOptions options = PolyImportOptions.Default(); options.rescalingMode = PolyImportOptions.RescalingMode.FIT; options.desiredSize = 2.0f; options.recenter = true; List<PolyAsset> assetsInUse = new List<PolyAsset>(); for (int i = 0; i < Mathf.Min(3, result.Value.assets.Count); i++) { PolyApi.Import(result.Value.assets[i], options, ImportDonuts); assetsInUse.Add(result.Value.assets[i]); // Update the Attributions Text attributionsText.text = PolyApi.GenerateAttributions(includeStatic: false, runtimeAssets: assetsInUse); } } private void ImportDonuts(PolyAsset asset, PolyStatusOr<PolyImportResult> result) { assetCount++; result.Value.gameObject.transform.position = new Vector3(assetCount * 2.5f, 0f, 0f); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class loadNewAsset : MonoBehaviour { public int assetCount = 0 ; // Reference the text element public Text attributionsText ; void Start ( ) { PolyListAssetsRequest req = new PolyListAssetsRequest ( ) ; req . keywords = "frosted donut" ; req . pageSize = 10 ; PolyApi . ListAssets ( req , GetDonuts ) ; } private void GetDonuts ( PolyStatusOr < PolyListAssetsResult > result ) { PolyImportOptions options = PolyImportOptions . Default ( ) ; options . rescalingMode = PolyImportOptions . RescalingMode . FIT ; options . desiredSize = 2.0f ; options . recenter = true ; List < PolyAsset > assetsInUse = new List < PolyAsset > ( ) ; for ( int i = 0 ; i < Mathf . Min ( 3 , result . Value . assets . Count ) ; i ++ ) { PolyApi . Import ( result . Value . assets [ i ] , options , ImportDonuts ) ; assetsInUse . Add ( result . Value . assets [ i ] ) ; // Update the Attributions Text attributionsText . text = PolyApi . GenerateAttributions ( includeStatic : false , runtimeAssets : assetsInUse ) ; } } private void ImportDonuts ( PolyAsset asset , PolyStatusOr < PolyImportResult > result ) { assetCount ++ ; result . Value . gameObject . transform . position = new Vector3 ( assetCount * 2.5f , 0f , 0f ) ; } }

Now we should see the attribution info display on our screen! It should include the title of the asset, the author, the url containing the model’s ID, and the license info.

Now we know that along with a large library of free 3D models to choose from, Poly also allows us to load them into our AR app on the fly and also handles attributions. That should be enough to kickstart your next AR project with Poly.

Poly is a great tool for game developers to quickly build AR apps populated with many different 3D models. It is also great for game developers who are trying to save on time and resources by adding assets into their game dynamically with Poly’s simple REST API. To check out some of the beautiful 3D models in the Poly library and to dig in to an in-depth guide and reference to the API, head to their website.

Poly assets used in this tutorial:

“Burger” by Poly by Google (Licence: Creative Commons CC-BY)

“Donut” by LaZZe (Licence: Creative Commons CC-BY)

“Donut 1” by Rachel Needle (Licence: Creative Commons CC-BY)

“Large Pink Frosted Doughnut” by Ruby “RubyDaSPLARK” (Licence: Creative Commons CC-BY)

“Pink frosted sprinkeled donut” by chocapic 360 (Licence: Creative Commons CC-BY)