From Unity To Corona

In 2018 I released a mobile app named Tappy Easter. In 2019 I released an update. Well, not really an update, more of a complete rewrite. Version 1.0 of Tappy Easter was written in C# using Unity. Version 2.0 is written in Lua using CoronaSDK.

This article will document my experience writing the same app using two different languages in two different game engines, and will cover the great and not-so-great of each.

Background

I have been using CoronaSDK since 2012 and have written several apps currently on the iOS and Android play stores. Some time in 2016 I picked up Unity since I wanted to try my hand at a 3D game. I spent a lot of time learning Unity, developing games for game jams, but I wanted to release something to the app store. Even though it was a 2D game, I decided to create Tappy Easter using Unity as a good test case.

Design

The game’s layout is fairly simple: a title screen, a level select screen, and the game screen, and some additional pop-ups and menus to move between the game scenes.

The game scene consists of a series of Easter baskets that are tapped to move a colored egg. The controls are quite standard and very simple from a development perspective.

The level select screen is a bit more complex… it consists of 20 level buttons on two panels. The user can scroll between two panels and can only select levels that have been unlocked. In this scene, the 20 level buttons are built using either a locked or unlocked graphic and if the level is unlocked and previously played, the number of stars that were awarded are also displayed.

Unity Development

Development took approximately four months, and it went very well. The Unity interface makes it easy to lay out your game screens, and I like using C#. Unity UI development is awesome, and the text features of TextMesh Pro give the game extra polish.

In addition to some assets I previously purchased, I also decided to purchase a couple of assets to make development a bit easier for this game. The code I wrote for swiping and tapping screen items was not really working as well as I wanted, so I purchased an asset to handle the mobile gestures. I also purchased an asset to simplify other features found in mobile games such as game services, advertisements, and rating systems. Since these features are platform dependent, using an asset to mange this was a no-brainer.

Development was a breeze… no issues with coding or screen design. It was now time to test on my devices and upload to the app stores.

Time To Compile v1.0

It felt like I spent more time getting the app to compile than I did to develop it, and this was becoming more and more frustrating.

You would think that adding Google Play and Admob would be easy since they are both Google products, but this was an exercise I never want to go through again. These libraries seem to be incompatible with each other since each library includes older versions of files that the other library needs. This caused so many incompatibility issues. After several weeks of research into the issue, it seems trial and error is the only way to get this resolved. Finally, I could get the app to compile and run under Android, but I am not 100% sure how I did it or whether I can do it again.

Now on to the iOS version. I imported the Xcode project generated by Unity which resulted in several hundred “warning” messages and some errors. Reading through tons of support messages, it appears that 200+ warnings can be ignored, but I don’t feel ignoring that many warnings is a great solution. Admob errors were also fussy, and again, I am not sure how I overcame the errors, but I got to a point where it compiled and ads were being displayed.

After more days than I can remember, I now have a working Android and iOS build, so time to put them on the app store!

Working On The Update

A few weeks later, I wanted to tweak a few things and put out an update which seemed a bit more difficult than expected.

I updated all my plugins, including Admob and Google Play (I had to due to some required Google changes), and again there were errors caused by file incompatibilities. This time, no matter what I did, I could not get these 2 plugins to play nice together.

What I also found interesting with the iOS build is that the file size of the v1.0 build was 120mb! Looking at the Unity logs, a lot of unused files and asset demo folders were included during the build, and I could not understand why. Reading through some forum messagess (since my question on the forum went unanswered), it appears that iOS builds do not really exclude everything that is not needed.

At this point, I decided not to update the app, and let it ride in its current behemoth state. Early in 2019 I decided to revisit the update and had the same issues. The frustration level was off the charts, and I convinced myself it would be easier just to start again using Corona… which is exactly what I did.

Corona Time

My previous experience with Corona, and utilizing the sound and image assets created for the Unity version, allowed me to put an improved version of Tappy Easter on the iOS and Android app stores in under 1 month.

Corona is somewhat of an underrated 2D engine, but it is robust and established, and this made development quite easy. There is a lot of things that Corona does that require a bit of work in Unity:

  • I did not have to manage aspect ratios and screen sizes. Just place your images where you want them, and Corona will handle it appropriately, no matter what display.
  • Admob and Google Play actually work without hours of tweaking. Include the plug-ins and start coding.
  • XCode not required!!! Just choose File -> Build and Corona will compile an app to an IPA file without needing a Doctorate in Xcode, and will create an Android APK file without needing to install all the Android libraries.

In order to have really nice fonts in Corona, I had to create images of text. Since this app is English only (at this time), that’s not an issue, but I would have to create text image files for every language I want to support.

As a result, I am currently working on a Corona plugin that will manage fancy text and I am encouraged by my results so far. My free plugin (GBC Language Cabinet) simplifies the management of language support, so utilizing this library with a text library should provide a great solution to multi-language fancy text.

My Unity vs Corona Experience
 UnityCorona
Development Time4 months1 month
File SizeiOS - 120mb
Android - 33mb
iOS - 11mb
Android - 10mb
Additional AssetsFingers Touch Gestures
EasyMobile Pro
none
StrengthsVisual Editor
Text features
3D
"One Button" build
WeaknessesXCode frustrationNo visual editor... images must be coded to screen
Text features
Conclusion

I love working with both Unity and Corona, and it seems that each tool has its strengths and weaknesses. No one tool can do it all.

For 2D mobile development, Corona (to me) is the better choice… it’s a great way to release a game quickly and easily. Tappy Easter is one of those games where Corona was the perfect choice.

For desktop, 3D, or perhaps more complex mobile games, I would consider using Unity. There are some really complex games written with Corona, as well as some desktop games, so the Corona platform would still be a consideration when evaluating my game requirements.

I do wish Unity could build mobile apps more simply, like Corona does.
Building a desktop app with Unity is so simple, so it should be possible to improve building for mobile. Building the app seems more complicated than actually developing it, but maybe I’m just spoiled.

[divider]

Johnny’s Flip Book Adventures – November Status

I just wanted to post a screen shot of both the classic “Space Mission Survival” mode and the Ludum Dare 42 mode of Johnny’s Flip Book Space Adventure.

Development is going well, and I am happy with the results.  I am currently working on audio, and after that I believe I will be working on a configuration/settings screen.

Keep checking here as well as on itch.io for updates.

 

[divider]

Another Unity Object Pool Update

It’s time for another update to my Unity Object Pool library. I previously wrote about it here and here, and this update streamlines the code a bit and makes it even easier to use. I am also going to open source this library (more on that later).

I’ve been using this version for some time and have had no issues, so it’s time to make it available. Feel free to grab a copy to use in your projects. If you like this library, and you want to see some features added, please let me know, or consider sharing your updates.

What Was Updated

  • This update no longer requires a Unity GameObject for every pool. All pools are stored in it’s own Queue and the Queues are placed in a Dictionary. When the library is started, it will create nested game objects under the main pool object and will then populate each pool with the correct objects. This makes it easier to see what’s going on in the Inspector.
  • When items are placed into the pool, the object name is appended with “(Inactive)”. When objects are taken from the pool, that is removed. Again, this makes is easier to see what objects are being used at any given time within the Inspector. Inactive objects are in the pool waiting to be used.
  • The library has been created as a Singleton so that it can be used throughout your project via the static Instance variable.

How To Use

  1. Download and import this asset into your Unity Project.
  2. Drag the GBC Object Pooler prefab into your Unity scene.
  3. Click on the prefab in your scene, and in the Inspector you will notice a script named GBCObjectPooler.
  4. Enter the number of pools you wish to create.
  5. For each pool, drag in a prefab, enter the number of items you wish to create in the pool, and the name of the pooled items.

As of this post, there are 3 methods.

GetPooledObject(string poolName)

This will return an item from the pool specified.
If the pool does not exist, or if there are no more items in the pool, null is returned.

ReturnToPool(GameObject object, string PoolName)

This will place the specified item back into the correct pool, and will disable it.

ItemsInPool(string poolName)

This will return the number of items still available in the specified pool.
If the pool does not exist, null is returned.

Open Sourced

I am placing the source code (with example) on github for all to use and update. This is a simple “quick and dirty” library and I would like to keep it that way, but I am sure there are a lot of other useful features that can be added to enhance functionality. I don’t want to add a lot of unnecessary bloat… there are some very good pooling libraries on the Asset Store that contain a ton of features, but my intent is to provide an easy to use pooling library, but let’s see where this goes.

It’s a small project, but it is my first open source attempt, so this is a learning experience for me as well.

Link to GitHub project

[divider]

My First (Upcoming) Unity Release

All of my previous game releases were written with CoronaSDK, but about two years ago, I decided to learn Unity. Since that time, I have used Unity for several game jams, but I have not officially released anything. Since September 2017, I have been working on a mobile game using Unity and I am planning on releasing it in the next couple of months.

I have three “Tappy” games released on mobile: Tappy Holidays, Tappy Valentines, and Pumpkin Patch Match (ie: Tappy Halloween). These are very basic games written in Corona, and I decided to create another simple Tappy game with Unity as a good first attempt. I present to you: Tappy Easter.

Tappy Easter will be my first new game in almost two years. It’s also my first released Unity game. I decided to try something “simple”  (although it became more complicated that I expected) so that I can learn what it takes to publish a mobile game with Unity. I already had a good understanding of C# coding, UI, graphics, etc. It was all of the additional “stuff” that makes a game that I had to learn. I decided to buy a couple of assets (in addition to the assets I already owned) to make it easier on myself. Here’s some detail around the new and additional things I encountered:

  • Mobile UI. I started working on swipe code myself, and decided to bite the bullet and buy an asset that helps with this. I purchased Fingers Touch Gestures, and decided to use that for my swipe code, as well as all the other tap code. What a time saver! Swipe, tap, gestures all included, and you can simulate it in the editor with your mouse.
  • Achievements. I purchased the Easy Mobile asset to help with integrating Google Play and Apple Game Center. Again, a great time saver. One call, and Easy Mobile takes care of everything. This asset has a lot of cool features to help with Achievements, Leaderboards, Advertisements, Ratings, and more.
  • Admob. Easy Mobile to the rescue again… so easy to configure and use.

Unrelated to Easy Mobile, I did have a hell of a time integrating Google Play and Admob on the Android version of Tappy Easter.  It took a couple of days to figure out and fix the issue. Turns out Google includes libraries in each asset that are incompatible with each other, so you have to be sure you are only importing the latest version of the libraries. A lot of time was spent looking up the problem and figuring it out. The solution is so simple but is not documented adequately enough.

Other assets I bought previously were DoTween and Text Mesh Pro… both are fantastic. Both are free, although there is an enhanced paid version of DOTween I recommend. DoTween is a very powerful and fast tweening library, and I use this in everything I develop. Text Mesh Pro is unbelievable for enhancing your text. I purchased it prior to Unity making this a free asset.

I also decided to learn Unity Analytics, especially for the Remote Settings feature. I can see this being valuable… once I understand it a bit more.

All in all, it was a great learning experience, and I expect Tappy Easter to be available some time in mid to late February.

[divider]

Ludum Dare 35 – Post Mortem

Another Ludum Dare in the books! Another great experience, another game released.  My game is called Shape Shifter Match Maker:

Shape Shifter Match Maker
Click picture to play and rate my game!

The Experience

This was my second LD and to be honest, I was not thrilled with the final list of themes, so my enthusiasm dropped a bit the day before. Once the theme (Shapeshift) was announced, I drew a complete blank on what game I should make. I spent more than a couple of hours hashing ideas and came up with nothing. At this point I figured I had to do something, so I decided to create some code to take a shape and change it. This was out of desperation, since I didn’t want to waste valuable time just sitting around and hoping an idea would come to me. Once the basic shape shift code was created, I was determined to take that code and wrap a game around it. The result was this game. I don’t normally recommend working like this, but since time is valuable I needed something.

I utilized Unity’s cube and sphere assets, but I needed a third model and decided to use a triangle. My Blender skills absolutely suck, but I managed to take a basic cube and make a pyramid out of it.

So now I have code to change shapes and colors, and a basic game around it.  Time to get going.

I recently bought a Tweening library called DOTween and decided to use that in my game. I didn’t have a chance to use the library before LD35, so this was an added unknown in the development of my game. Tweening libraries are fantastic… you can easily move, rotate, and animate objects with some cool effects. I used DOTween to:

  • Rotate, shape shift, and color shift all the 3D objects in the game.
  • Warp in the additional level objects.
  • Animate the colored backgrounds.

Also new to me was the use of audio tools bfxr and Otomata. Both (free) tools are incredible for creating sound effect and music. Otomata was a gem of a find. I was very pleased with the outcome of the music.

Thoughts On My Game

I am not sure how I feel about my game. It’s not what I expected to develop, but then again, I didn’t expect to develop anything at one point. As I play it, I do tend to enjoy it.

About a day after I submitted the game I had an idea to use the left and right mouse buttons to change the shape and colors. Hmm… I wish I thought of that while I was in development mode. I think that would be better than clicking on buttons.

An hour after my idea for improved controls, I had a brainstorm for a much better game. I am not going to explain it here, since I am seriously considering developing this new idea.

What Went Right
  • I finished and uploaded a working game within 48 hours.
  • Great opportunity to learn and use new tools DOTween, bfxr, and Otomata.
  • I decided to use C# Events instead of linking to scripts via Unity’s “Find” and “GetComponent” (where appropriate) like I did in my previous LD entry. I prefer a loose coupling, but this can get out of hand very quickly if you are not careful. I also prefer C# Events over Unity Events, but that may change after I revisit Unity’s manual for another read-through.
What Could Be Better
  • I had a tough time thinking of an idea… I guess I was very short sighted in using this theme.
  • Better game play is needed. The game does not get harder after the 3rd set of controls warp in.
  • Using multiple new tools during a 48 hour game jam is a little stressful. Glad I did it though, since it greatly improved the game.
Where to Go From Here

Of course, I am looking forward to LD36. In the meantime, I need to decide if I should continue to work on my current project, or shelve that for a bit while I look into developing the new version of Shape Shifter Match Maker. I guess the comments in the review section of my LD entry will help me decide that.

My Improved Unity Object Pool Class

Nice, little updates to code are… well, nice! I’ve been using a home-grown object pooler in Unity, and you may recall I wrote about that here.  It’s a very simple, yet effective way of creating a pool of objects.

Originally, I used List<GameObject> and looped through the list to find an unused game object. Thinking about it a bit, I realized I could use a queue instead.  Here’s the updated code:

using UnityEngine;
using System.Collections.Generic;

public class Pooler : MonoBehaviour {

    public GameObject pooledObject;     // object to pool, drag into Inspector
    public int pooledAmount;            // number of objects, drag into Inspector
    public string objectName;           // name of object, enter into Inspector

    private Queue<GameObject> pooledObjects;

    /// <summary>
    /// Inits the object pool.  Renames the pool objects to the objectName
    /// </summary>
    void Awake() {
        pooledObjects = new Queue<GameObject>();

        for (int i = 0; i < pooledAmount; i++) {
            GameObject obj = (GameObject) Instantiate(pooledObject, Vector3.zero, Quaternion.identity);
            if (objectName != "") obj.name = objectName;
            obj.SetActive(false);
            obj.transform.SetParent(transform, false);
            pooledObjects.Enqueue(obj);
        }
    }

    /// <summary>
    /// Gets the pooled object.
    /// </summary>
    /// <returns>The pooled object or null if all objects are used.</returns>
    public GameObject GetPooledObject() {
        if (pooledObjects.Count == 0) return null;
        return pooledObjects.Dequeue();
    }

    public void ReturnToPool(GameObject obj) {
        obj.SetActive(false);
        pooledObjects.Enqueue(obj);
    }
}

Using Queue<GameObject>, there is no need to loop through a list.  The Dequeue statement at line 33 will remove the first item from the queue and return it. I added the ReturnToPool method, so I can disable the object and add it back to the queue when I am done with it.

This object pooler is a basic and easy to use. Feel free to use or modify it if it works for you.

To use it, place this script on an empty game object, drag in a prefab, choose how many objects you want to create, and name it something.

Object Pooling in Unity

In my previous post, I covered object pooling in CoronaSDK. This article will cover object pooling in Unity, using C#. While the concept of Object Pooling is the same no matter what language, there are obvious syntax and set-up differences, and we’ll cover those Unity specific things here.

I am going to demonstrate a very simple object pooling class to get you started. There are more robust solutions on the Internet and in the Unity Asset Store, and each solution is a bit different, but this is what I have been using and it demonstrates the concept as well.

Step 1 – Initial Set Up

To use this solution, you need a couple of things:

  1. A prefab object that you will use as the object to pool. For this example, we’ll just create a cube, and we’ll call it “EnemyPrefab”.
  2. An empty Game Object. For this example, let’s rename it to “EnemyPool”.

Once you have a prefab and an empty game object, create a new C# script called Pooler. Here is the code for this script:

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

public class Pooler : MonoBehaviour {
	
	public GameObject pooledObject;		// object to pool, drag into Inspector
	public int pooledAmount;			// number of objects, drag into Inspector
	public string objectName;			// name of object, enter into Inspector
	
	private List<GameObject> pooledObjects;
	
	/// <summary>
	/// Inits the object pool.  Renames the pool objects to the objectName
	/// </summary>
	void Awake () {
		pooledObjects = new List<GameObject>();
		for (int i = 0; i < pooledAmount; i++) {
			GameObject obj = (GameObject)Instantiate(pooledObject, Vector3.zero, Quaternion.identity);
			if (objectName != "") obj.name = objectName;
			obj.SetActive(false);
			pooledObjects.Add(obj);
		}
	}

	/// <summary>
	/// Gets the pooled object.
	/// </summary>
	/// <returns>The pooled object or null if all objects are used.</returns>
	public GameObject GetPooledObject() {
		for (int i = 0; i < pooledObjects.Count; i++) {
			if (!pooledObjects[i].activeInHierarchy) {
				return pooledObjects[i];
			}
		}
		
		return null;
	}
}
 Step 2: Pool your Prefab

Pooler PropertiesAttach the Pooler script to the empty game object, and look at the Inspector. You will notice 3 public properties:

  • Pooled Object – drag your prefab here. This is the object you want to pool.
  • Pooled Amount – enter the number of pooled prefabs you want.
  • Object Name – the name of the object. More on that later

Pooler HierarchyWhen your project is run, you will see a number of pooled objects in your Hierarchy view.

See line 20? I like to rename my objects when they are created, but this is up to you how to rename them, if at all. If you enter text in the Object Name property, the object is renamed.

Step 3: Use Objects in Pool

To get an object in the pool:

GameObject obj = GameObject.Find("EnemyPool").GetComponent<Pooler>().GetPooledObject();

or, to break it down:

GameObject gameObj = GameObject.Find("enemyPool");
Pooler enemyPool = gameObj.GetComponent<Pooler>();
GameObject pooledObject = enemyPool.GetPooledObject();

To return an object to the pool, inactivate it:

gameObj.SetActive(false);
That’s it!

There you have a very simple object pooler class. Of course you can expand on this class to do all sorts of things: update other properties, allow the class to grow if needed, etc.

My Development Shelf

I am sure I am not the only developer with a bunch of ideas, partially developed apps, or proof of concepts “on the shelf”.  For some reason I seem to have quite a few.

  • I recently played around with a few concepts that I could not roll into a game I wanted to develop.  One was a card game, another was some LiquidFun functions.  They are now on the shelf for a later day.
  • I have a game a started 4 or 5 times over the past 3 years.  I think I have the basic idea worked out, but I am still trying to figure out the finer points.  So, it’s been on the shelf for over a year without looking at it.  I really want to finish this one.
  • My recent project, the rewrite of Space Mission Survival, was recently put on the shelf.  I liked where I was in the development process, but decided a rewrite wasn’t going to be enough to get anyone to play the game on the PC or consoles.  It’s been on the shelf for about 2 weeks, but I recently dusted it off and it’s back as my project Du Jour.
Space Mission Survival Off The Shelf

My latest thought is that the rewrite of Space Mission Survival for consoles and PC will be a more high-intense, fast action game with power-ups, multiple enemy types, and multiplayer action.  This is a bit different than my original thought of developing a straight port, but I think its the way to go.  I still love the game play of the current Space Mission Survival, so I think I am going to add this “classic” mode to the new version.  Two… two… two games in one!

Since taking this project off the shelf, I yet again decided to start over (as I always seem to d0), but kept as much code as I could.  Lots of code was reused, but there were instances where new stuff I learned greatly improved ways to do things, thereby reducing code.  InvokeRepeating is awesome, and taking advantage of Mechanim for simple animations is another time saver.  Going to add some particle effects too!

We’ll See

I was planning on using CoronaSDK to develop a bunch of smaller mobile games this year.  I did release one game in January.  The Unity development of Space Mission Survival may impact the development of some Corona projects, but we’ll see.

One of the reasons why some of my apps go back on the shelf is that I am easily discouraged (due to limited feedback) and quick to change gears (finding something new, exciting, and challenging).  Right now I am into developing Space Mission Survival, but we’ll see.

Maybe I’ll pull one of the other things I mentioned off the shelf as well… we’ll see.