Converting a Unity3D project to PlayCanvas - Part 1

  • What is Unity3D? What is PlayCanvas?
  • Why convert a Unity project to PlayCanvas?
  • Where to begin?
  • How to transfer the assets to PlayCanvas?
  • How to transfer the Unity entities to PlayCanvas?

In this tutorial we will dive in the process of converting a Unity3D game to a game running in PlayCanvas.

This tutorial assumes a minimal knowledge in using the PlayCanvas editor.

Unity 3D Flappy Birder Style Example Game

 

What is Unity3D? What is PlayCanvas?

Both are platforms that enable a developer to create 2D, 3D and VR content, and most commonly games, thus they might be mentioned as game engines.

Wikipedia: Unity3D

Unity is a cross-platform game engine developed by Unity Technologies, which is primarily used to develop video games and simulations for computers, consoles and mobile devices. First announced only for OS X, at Apple's Worldwide Developers Conference in 2005, it has since been extended to target 27 platforms. Six major versions of Unity have been released. At the 2006 WWDC show, Apple named Unity as the runner up for its Best Use of Mac OS X Graphics category.

Wikipedia: PlayCanvas

PlayCanvas is an open source 3D game engine/interactive 3D application engine alongside a proprietary cloud-hosted creation platform that allows for simultaneous editing from multiple computers via a browser-based interface. It runs in modern browsers that support WebGL, including Mozilla Firefox and Google Chrome. The engine is capable of rigid-body physics simulation, handling three-dimensional audio and 3D animations. PlayCanvas has gained the support of ARM, Activision and Mozilla. The PlayCanvas engine was open-sourced on June 4, 2014.

How can they be accessed?

Unity3D is a desktop application that runs on Windows, macOS and Linux which provides a visual editor alongside a scripting framework that uses C#.

PlayCanvas is a visual development platform for interactive web content. Both the tools and the web apps you build are powered by HTML5. The platform is web hosted and can be accessed from any device that runs one of the supported web browsers.

Where they can be deployed?

Unity3D can deploy to 25+ platforms across mobile, desktop, console, TV, VR, AR and the Web. It is advertised as having more platform support than any other creation engine, and that is quite right.

Unity3D: More platform support than any other creation engine

PlayCanvas builds HTML5 web apps which means they can run in any browser that supports WebGL. A simple one-click publishing is provided that gets your application live on the internet hosted by PlayCanvas for free. Alternatively download your application for self-hosting on your own web server.

Using cocoon.io or a similar service you can wrap your web app in a native container to deploy on mobile devices like iOS and Android.

 

Why convert a Unity project to PlayCanvas?

Now this is the million dollar question: normally you shouldn't as Unity can build and deploy to WebGL. Which means it can export an HTML5 build of your app that will run inside a browser environment. Much like PlayCanvas.

But the way that Unity converts your C# project to an HTML5 (Javascript) application isn't so straightforward. The C# codebase gets converted to C++, then is compiled from C++ to Javascript using Emscripten. This process creates heavy and large codebases, which even for small applications can result in hundreds of thousands lines of code. The application might be slow and right now it doesn't run on mobile devices.

Here is an article that compares Unity and PlayCanvas on this specific deployment option.

What is Emscripten?

Emscripten is a source-to-source compiler that runs as a back end to the LLVM compiler and produces a subset of JavaScript known as asm.js. This allows applications and libraries originally designed to run as standard executables to be integrated into client side web applications. asm.js can be compiled by browsers ahead of time meaning that the compiled programs can run much faster than those traditionally written in JavaScript.

For this reason there is a trend in using a native WebGL engine to convert a unity project and push a build that can natively run online. Of course this comes with its own issues:

  • Added cost for converting to WebGL
  • Added cost for maintaining two codebases.
  • The experience might not be 100% the same due to different supported features by each platform.

But at the end, as of now, this is the best option in getting the best experience out of your application when deploying online.

For the purpose of this tutorial we will be converting an example Unity project to PlayCanvas. The original Unity project can be downloaded for free here:

Asset store, Flappy Bird Sample Project

 

Where to begin?

At the beginning it might be difficult to decide where to begin, as normally happens when moving to a new platform. We will try to give emphasis and illustrate the similarities and differences between the two platforms. Both platforms use a visual editor to setup and navigate through the project and share a lot of similar pipelines.

You can find a thorough introduction on the PlayCanvas editor here.

PlayCanvas visual editor
PlayCanvas Editor

We will build this project in multiple parts, starting in this first part on how to transfer the assets from the Unity project and prepare the PlayCanvas project settings and entities.

So, head over to your Projects dashboard and create a new blank project.

PlayCanvas new project.

 

How to transfer the assets to PlayCanvas?

Let's begin by examining the types of assets that the Unity project references. We can find the following types of assets:

  • animations
  • fonts
  • prefabs
  • scripts
  • sprites/textures

The ones in bold are asset types that are supported in PlayCanvas out of the box, which means that with a simple drag and dropping we can upload those assets on our new project. 

Head over to the Assets panel and create three new folders named:

PlayCanvas Assets panel

PlayCanvas Asset Tasks panelFonts and Textures

Before uploading the assets we need to know that PlayCanvas automatically can run various asset tasks on the uploaded assets. You can find the supported tasks on your project settings, on the Asset Tasks panel. There is an asset task that will be problematic on our case that we need to disable, and that is Textures POT. This tasks is responsible with converting all uploaded textures to the nearest power of two.

This can improve performance and is useful in some older devices that supported only POT (power of two) textures. Since our unity project uses non-POT textures we need to disable that.

Now we are ready to upload the supported assets (font and textures) on their respected folder, by drag and dropping from the original Unity folder. After the loading is complete you will see the thumbnails of the assets in a similar manner like in the Unity editor.

PlayCanvas Assets panel with textures loaded

PlayCanvas texture asset properties.We are almost finished, we only need to set the Wrap Mode on our sprite textures the same as in Unity.

  • Wrap Mode in PlayCanvas terminology is called addressing mode, and can be found on the texture settings, that open up when selecting a texture. They are set for each dimension so you will find two properties named Address U and Address V.

Set both properties to Clamp for all of the sprites.

What is texture wrapping?

The wrapping mode determines how the texture is sampled when the texture coordinates are outside of the typical 0-1 range. For example, Repeat makes the texture tile, whereas Clamp makes the texture edge pixels be stretched when outside of of 0-1 range.

Animations

If you have been studying the PlayCanvas docs (good for you!) you will most likely seen that PlayCanvas engine supports animation. But don't get confused, that is only boned animation mainly used in 3D models.

It wouldn't be much use to us here in this 2D project. PlayCanvas doesn't have any built-in animation editor like the Unity editor provides. This means that we can't use the animation assets found in our Unity project. We will have to replicate those animations in code, and we will do just that later.

Prefabs

The Unity prefabs system is a powerful concept. The ability to pack entities with their components to simple reusable assets is very useful. Sadly PlayCanvas, as of now, doesn't provide any similar concept.

We will be replicating the Prefabs found in the unity project in the PlayCanvas entity Hierarchy.

Scripts

Regarding scripting both Unity and PlayCanvas use a similar concept. The developer can write script objects, attach them to entities using a script component and the entities will create automatically an instance of that script.

In Unity the scripting language used mainly is C#, in PlayCanvas we use Javascript. This means that we will have to convert the C# to JS (Javascript). This might seem difficult, especially if you have knowledge only of one of the two. Good thing is that both languages are high level languages, with an OOP code paradigm and widely used. This means that there is plenty of support and documentation for both.

We will handle the C# -> JS script translation in a coming tutorial part.

 

How to transfer the Unity entities to PlayCanvas?

Unity 3D editor hierarchyNow let's handle our next step in preparing the PlayCanvas project. We need to create the entities that will hold and instance in our game world the loaded assets.

What is an entity in PlayCanvas?

The Entity is the core primitive of a PlayCanvas game. Every object in your game is an Entity, but on it's own an Entity is nothing more than a position and orientation in space. In order to give an Entity a behavior you must add Components. The PlayCanvas Engine contains built-in Components which add lots of useful behavior such as rendering a 3D model or playing audio. Using the Script Component custom behavior can be written in Javascript.

To make it easier to read both projects we will re-create the exact same hierarchy found in the Unity project. 

Remove all entities found under the Root entity by selecting them, right-clicking on them and selecting Delete.

Now let's start adding the following entities one by one. To do that, click on the + icon found on top of the Hierarchy panel and select the appropriate type. Here is the list of entities with their name and type that we will create on this step.

  1. PlayCanvas entitiesBird, type Plane
  2. GameControl, type Entity
  3. Main Camera, type Camera
  4. Scenery, type Entity
  5. Canvas, type 2D Screen

To change the name of an entity, click on it and at the right on the Inspector you can type  a new name. All this in a similar to Unity manner.

Let's setup now these entities in accordance with the Unity properties.

1. Bird

Select the Bird entity and attach an additional script component (we will use that later).

Set the X rotation to 90 degrees. We will be using the X and Y for movement, to simulate the 2D axis system Unity is using.

Create a new material in the Scripts folder called matBird, and drag and drop the BirdHero.png on the Diffuse Map slot of this material. Now drag and drop this material on the Model Component of the entity, on the Material property. Now you will notice two things:

  1. Everything is dark, very dark! This happens because we have removed lighting.
  2. All three frames of the texture are rendered at the same time. This happens because PlayCanvas doesn't provide any sprites pipeline in the editor.
PlayCanvas creating a 2D plane.

To resolve the darkness issue, head over to your project settings, and on the Rendering panel change the ambient color to a full white (255,255,255).

Ambient color normally doesn't affect the objects when using the full PBR and cubemap rendering pipeline. But now because we have removed all lights we reside only to the ambient color to light the scene. Setting it to full white allows the sprites to be rendered as they are, without any light affecting their color. Which is perfect for our small 2D game!

PlayCanvas setting the ambient color.

To, temporary, resolve the sprite issue we can change the U tiling of the texture on the matBird material properties from 1 to 0.33. That way 1/3 of the texture will be rendered on the plane. We will deal with sprites and animation in a coming part.

PlayCanvas material offset and tiling.2. GameControl

This entity will be used to instance the scripts that control the gameplay. For the moment attach only a script component.

3. Main Camera

PlayCanvas camera settingsChange the properties of the camera to match the ones shown in the image. The main difference is that we will be using an Orthographic camera instead of the default Perspective.

What is an Orthographic camera?

Orthographic projection (sometimes orthogonal projection), is a means of representing three-dimensional objects in two dimensions. It is a form of parallel projection, in which all the projection lines are orthogonal to the projection plane, resulting in every plane of the scene appearing in affine transformation on the viewing surface. The obverse of an orthographic projection is an oblique projection, which is a parallel projection in which the projection lines are not orthogonal to the projection plane. This is especially useful in 2D games as the sprites don't stretch or scale based on their position on the canvas.

4. Scenery

This will be a simple entity holder, no components required for this entity.

5. Canvas

This will be the UI holder that will render all of our interface entities in screen space. For the moment leave all of its properties to its default values.

 

Are we finished?

Not at all! If you managed to reach this point, you can hit launch and enjoy your textured 2D plane. Don't despair though, you have everything in place to create one more flappy bird clone.

You can find the public PlayCanvas project used for this tutorial here.

In the next part we will build our background scenery, add level objects and start coding the basic gameplay.

PlayCanvas Launch
https://playcanv.as/index/1q0nFfAd/, A not so interesting, for the moment, project.

 

Converting a Unity3D project to PlayCanvas - Part 2