2016/09/16

Quick tip: Using Unity Actions to set default states on objects

So as I was working on a project that has a bunch of UI panels I kept forgetting to disable certain panels before running the game or before committing it and my client would see the panels with the loading screen. Sure I could add a line to the controllers I have set up to set the default state, but there's a bunch of controllers, not all of them have the panel assigned to them at start, not all of them are disabled (some are alpha 0, some are scale 0), and it's really best when an object maintains its own default state. So I said to myself, "I really need a universal script to do this. Wouldn't it be great to have some sort of drag-drop interface to do this?" I didn't really want to write a custom inspector for it since that would take 2 scripts. Then it occurred to me: BUTTONS they have on-click events. That's what I want. And boy was it easy!

So all you have to do is create a MonoBehaviour derived class. Declare using UnityEngine.Events, declare a public UnityAction variable. Then in your Start() method just Invoke() that event. Super simple. Here's the code:



Way too easy. Of course, you could extend this to also do Awake, OnEnable, OnLevelWasLoaded, OnApplicationPause, OnBecameVisible/Invisible, OnApplicationQuit, and OnDisable (I'd highly recommend avoiding using any of the main loop events). A very neat and clean way to do a simple delegate that's assignable from the inspector and can set the value on pretty much any component.

I hope you all find this as handy as I have. Feel free to post a more extended version here if you like sharing with others.

As always, thanks for reading!


On a personal note, my wife just published her first book! If you like kick-ass female protagonists, spies, and a bit of sci-fi then please check out her book on Amazon.

2016/08/27

Unity 3D Tutorial - Custom Transform Inspector

Hi everyone!
One of the awesome things about Unity is you can customize the editor to add all sorts of cool functionality. This article will show you how to override Unity's transform inspector with a more useful customized version. The Custom Transform Component includes:

  • The ability to view and edit the quaternion rotation (nice for experimenting and learning how quaternions work). 
  • The ability to show the local axes in the Scene view even when the object is not selected.
  • Some special operations for aligning to other objects, random rotation, random scale, and random position.

Here's what the final product will look like:
Custom Transform Inspector



Part I: Extending the Default Transform Inspector


Overriding the Defaults

First, thing's first. We'll need to recreate Unity's transform inspector (not completely necessary). To make any custom editor scripts you'll first need a folded called "Editor" in your Assets folder. This is a special folder that Unity looks in to for scripts that can only run in the Editor i.e. any script using UnityEditor;. You're not limited to one Editor folder per project so you can organize your editor scripts right alongside your MonoBehaviour scripts if you like. More info on on Unity's special folders can be found here. The UnityEditor namespace This gives us access to a whole bunch of awesome tools for writing editor windows, inspectors, importing assets, and pretty much anything that you need in the Editor. 

The first part of our script is a bit boring and doesn't really add any functionality to the Transform component. Some other notes before proceeding:
  • Custom inspector scripts need to inherit from Unity's Editor class.
  • To indicate what component (in our case the Transform component) the custom editor is for we will use the CustomEditor attribute.
  • Very commonly, you'll want to be able to select multiple items simultaneously and edit them. For this you'll need to add the CanEditMultpleObjects attribute. There are some caveats to this and you may need to write your own methods to apply changes to all selected objects as in the example below.
The first part of our class will basically recreate Unity's transform component. Unity draws the inspector in the method OnInspectorGUI() we will override this to make our custom inspector. Now, you don't need to recreate the default inspector (the part that shows position, rotation, and scale). I'm doing it here to give you insight on how custom editors work,  If you just want to use Unity's default then you can call base.OnInspectorGUI() from your override of OnInspetorGUI(). As you may see from the extents of the code below, that may be your preferred option.



Some extra explanation beyond the comments as to what's going on here. First, we set up a class level Transform (aptly named _transform) to hold the transform of the target (the selected object) so that we can refer to it throughout the class. We override OnInspectorGUI() and immediately cast target (a property of the Editor class) to a Transform type and set _transform.. Then we call our new method, StandardTransformInspector()

In the StandardTransformInspector() method we have a few things going on. First, we set up some bools to flag when a value is changed in the inspector and we store the initial position, rotation, and scale of our transform so that we can make a comparison later. Then you'll see three spots where we check for changes with EditorGUI.BeginChangeCheck() and flag our bools if a change has occurred by checking EditorGUI.EndChangeCheck(). Once that has finished and when know what if something has changed we now use Undo.RecordObject() to record the state of the object before any change has been made (this allows use to Undo the operation). Then we simply apply only the changes that have occurred.

Next, we have some adjustments to make to get our inspector to work like Unity's default inspector. Since we're using BeginChangeCheck() and EndChangeCheck() our changes will only be applied to the last selected object. So this basically breaks multi-selection editing which is what we're fixing next.To help us out I created another method, ApplyChangesOnly(), which will only apply a change to the x, y, or z value of the vector if it was changed in the selected transform. So if you change the x position it only changes the x position of all selected objects. Similarly I set up an undo state if anything will be changed, then iterate through all of the selected transforms (retrieved with Selection.transforms) and apply changes when it is appropriate.

That'll cover all the changes we need for recreating the default inspector for transforms. The only actual change I made over the default is I named the "Rotation" fields to "Euler Rotation". This is just so that we can see how to do this, and we'll be showing the Quaternion rotation in the inspector next.



Showing the Quaternion Rotation

Quaternions are what Unity (and many other 3D applications) use to store rotational information. They're a bit complex and not as intuitive as euler angles (degrees for x, y, and z). However, they are a necessity in 3D applications because euler angles don't fully describe rotation and the suffer from Gimbal lock. Check out the links to learn more on these. A discussion on Quaternions go well beyond the aim of this post and, honestly, I'd probably do a bad job explaining them. A quaternions are often a mystery to many and I decided to expose them in the inspector so that we can view and optionally edit them to get a better understanding of their behavior.

This section of the inspector will use a foldout (the little arrow head that shows more info when clicked). To maintain the state of the foldout we use a bool (is it open or closed?) and we'll use a new method, QuaterionInspector(), to display the quaternion's values.We'll also need to add a call to the method in OnInspetorGUI() as can be seen below:



The new QuaternionInspector() method uses familiar components as the StandardTransformInspector() method, but also uses EditorGUILayout.Foldout() to tell us whether the foldout should be open or not. A special note here: I used a static bool to store the state of the foldout. This means that when you open the foldout for any game object they will all be open since they're using a global static value. This decision was made because I didn't like opening it on one object, then making a multiselection and having to open it again. There's also a couple utility methods for converting the quaternion to and from a Vector4 since Unity doesn't offer a GUI item for quaternions and quaternions at their base are Vector4s, Those utility methods are pretty basic so hopefully you'll understand without extra explanation. Here's the new chunk of code we add to get it all working:



Now we have a custom inspector for transform components that shows us (and allows us to edit) the quaternion rotation. Pretty cool, but not overly useful. Next up we're going to add some utilities to our inspector to get the most out of it.



Showing the Local Axis

Oftentimes I've found that I'll really need to see the direction an object is pointing when I don't have it selected. It can be a pain to try to align rotations when you can't see the rotation of the object you're trying to align to! So I created a simple MonoBehaviour class that does just that. Now, you don't need the custom transform component for this, but the goal here is to show you how to integrate another component with your custom inspector. We could control all of the values of the ShowLocalAxis component via our custom transform component, but for such a simple component it is pretty pointless. Besides Unity already exposes the only variable we have in the component: handleLength. The goal here is to show you how to properly add and remove a component from another component via the inspector.

Here's the ShowLocalAxis class. It's pretty short and makes use of OnDrawgizmos() to show some lines that represent the axes of the object it is attached to. It allows for variable length of the lines (handleLength) which have been limited using the Range attribute. The Range attribute sets up a nice slider in the inspector for us. We are also using the HideInInspector attribute to prevent Unity from showing a public bool, destroyWhenSafe, whose purpose I will explain in a bit. Otherwise, the class should be pretty straight forward. It is just drawing a line on the local x, y, and z axes. To set the Gizmo's space to the object's local space we set Gizmos.matrix to transform.localToWorldMatrix.



To accomplish safe destruction of component via another component we'll need a custom inspector that waits for the proper time to destroy the component. Otherwise, we'll get some nasty errors in Unity. The below script does just that. We don't care about any special display, but since we used HideInInspector and Range in ShowLocalAxis, we'll use base.DrawDefaultInspector() to show the default view instead of base.OnInspectorGUI() that I mentioned before. So what happens is our custom transform component will set the destroyWhenSafe bool to true, then when the editor's state is Repaint we can safely destroy the ShowLocalAxis component. 



Now we have our component all set up, let's integrate it with our custom transform component. For this we'll make a new method called ShowLocalAxisComponentToggle() and change our CustomTranformComponent's OnInspectorGUI() to so it calls the method like this:



In Next up is the ShowLocalAxisComponentToggle() method, For this we'll need a private bool, showLocalAxisToggle, that will be used to toggle on/off the ShowLocalAxis component. And we'll need a First, we start off by adding some padding above the rest of the GUI elements with two calls to Unity's EditorGUILayout.Space() method. Next we attempt to see if there is a ShowLocalAxis component attached to the game object. If there is then we set our showLocalAxisToggle to true and display it in the inspector. This time we're going to use a horizontal layout (which starts a horizontal section where the GUI elements will be placed) by calling EditorGUILayout.BeginHorizontal(). Then we use a EditorGUILayout.LabelField(), start to monitor changes, and display a EditorGUILayout.ToggleLeft() with a corresponding label of "on" or "off" based on the existence of the ShowLocalAxis component. If the toggle changes value then we add the component and move it up to the second position so that it is right under the transform component. If we're toggling the ShowLocalAxis to off then we flag it with destroyWhenSafe and allow the ShowLocalAxis component to destroy itself when it is safe to do so. The full method looks like this:



That takes care of showing the local axis. Now we've learned how to create custom inspectors, do some layout, show axis line gizmos, and safely add/remove a component from another component. In the next section I will show you how to add even more functionality to the transform component. We'll set up methods for aligning selected game objects to each other, randomly rotating them, randomly scaling them, and randomly positioning them. Each of which can be very helpful in speeding up level design.






Part II: Special Operations


This section is split into subsections for each of the Special Operations. First, I'm going to show the full code for handling an animated foldout for showing/hiding the special operations. First, we need to have a class-level AnimBool object to maintain the state of the foldout, and a static bool to set the foldout states on all custom transform components globally. We set assign the AnimBool in OnEnable() which fires when a game object is selected in the editor. The states will then be properly set and we'll need to add a call to the SpecialOperations() method in our OnInspectorGUI() method like we've done before. For now, you won't have the AlignmentInspector(), RandomRotationInspector(), or RandomPositionInspector() methods, so you can just create stubs for them now if you like. But we'll cover them in the following sections.




Custom Button

Before we dig in, each of these inspectors will have buttons associated with them. Unity's default for an inspector button is to stretch its width to fit the inspector window. I don't really like that so I went ahead and created my own button. First I define a GUILayoutOption to set the  width of all the buttons to 200 (I found this number after I made all my buttons and could see their width). Then in the Button() method I wrap everything in a horizontal layout, add flexible spaces to the left and right of the button (this centers it), I then get the bool value from Unity's GUILayout.Button() so I can return it from the new method.





Alignment Inspector

The Alignment special operation will allow us to select multiple objects and line them up on their X, Y, or Z axis (or any combination of). This can be quite handy when doing level design. Definitely much better than having to figure out your snap interval or manually inputting position values. First thing we're going to need is a couple of enums. AlignToType is just either the last selected GameObject or the first selected GameObject. AxisFlag is a bit flag enum that allows us to make any combination of X, Y, and/or Z (the values you see are bits - i.e. 2 to the power of 0, 1, and 2 respectively). Then we set some default values up for these in alignTo and alignmentAxis. Like so:


Next up is our method to actually perform the alignment operation, this is called AlignTo(). First it gets an array of all of the selected transformas then it determines the index in that array (targetIndex) of the transform (or GameObject) we'll be aligning to. This is index 0 for the first selected and the last index of the array to align to the last selected transform. Then we iterate through all of the selected transforms and set their positions that should be aligned to the position of the selected transform. While doing this for loop, we ensure we skip over the selected transfor, because it makes no sense to move it to itself. Finally, we use Undo.RecordObject() so that we can reverse these operations.Some of you may be familiar with bitwise operations and may see the & in the conditions. Others of you are probably wonder what statements like
if ((axis & AxisFlag.X) == AxisFlag.X)
actually mean. The single & is a binary AND operator. What this does is it copies the bit to the results IF the bit exists in both operands (axis and AxisFlag.X). So if axis contains the bit for AxisFlax.X the result will be AxisFlag.X. This is why we're using powers of 2 for our AxisFlag enum's values. Basics on bitwise operators in C# can be found here at tutorialspoint.com. The full AlignTo() method is as follows:


Finally, we get to our AlignmentInspector() method which will display this special operation in our inspector. We're now making use of some enums, so there's two new methods for that - EditorGUILayout.EnumPopup() and EditorGUILayout.EnumMaskField(), The EnumPopup will allow us to select from a single enum value (our align to first/last selected) while the EnumMaskField will allow us to pick from any combination of enum elements (as long as they're powers of 2). It's also important to note here that these two methods return a generic enum so we must cast them back to our enum type to ensure they're correct. The we set up a string to hold our button label if only one game object is selected. We check to see if multiple game objects are selected. If they are we label the button more appropriately and enable the button. Finally we check to see when the button is pressed and if it is we execute AlignTo(). The following code illustrates this in its entirety:





Random Rotation Inspector

The Random Rotation inspector doesn't really cover anything new. In brief we're doing many things similar to the Alignment inspector. We set the axis flag(s) for what axis to rotate on, change the button label to indicate if 1 or more transforms are selected, then apply a random rotation (in euler angles) to the appropriate axis. See, things are getting easier!





Random Scale Inspector and Random Position Inspector

Last, but not least, are the Random Scale and the Random Position inspectors. These are also pretty easy now that we've gotten through all the drudgery. No new concepts appear here other than using a min and max value for the random value. The reason for this is that we need some bounds for our random value. With rotation, that's simple (0-360), but with position and scale... it could be anything to +/- infinity. So we ask the user to set those values in the inspector (of face the consequences!). The code below completes our custom inspector:





Final Thoughts (and some homework)

Ha! Didn't think you were going to be given homework, did ya? 
All of this was done to provide you with a practical example of customizing Unity's inspectors. You can apply these to your own classes, or override inspectors that you don't like (or think need more functionality). This is one of the many features that makes Unity powerful, it's extendible. Not only can you make these custom inspectors to help you with tasks, but you can also make custom context menus, custom menus, and editor windows. My rule is: if I'm going to be doing something a lot, then why not have a script do it for me. One example is: I ran into a project with about 60 scenes (yeah...) each scene had its own camera, like usual. Well, my client wanted to change settings on those cameras. I don't want to think how long it would have taken me to go through all of those scenes. And what happens when the client wants to make another adjustment to all the cameras (they did a few times)? Or if I miss something because I was trying to do it fast. Unity editor scripting to the rescue! I spent maybe an hour writing a custom script that would go through every scene and change the main camera to the settings I wanted. Changes now take about 1 minute instead of a couple hours. I sure was glad they were using Unity.

On to the homework! 
The Custom Transform Inspector isn't quite complete. It needs at least one more thing: an even distribution component. Wouldn't it be amazing to select a few objects, align them on an axis and then make them nicely distributed? Yes, it would! Your task is to add on to the custom transform inspector and make this happen! The first person to do this will get a free copy of my Mobile Screenshot Helper asset from the Unity Asset Store. Just make the code neat and clean and keep to the same naming conventions Im using in the script. 

Here are the full scripts for you to play with:

As always, thanks for reading!



.

2016/07/29

Unity 3D to IBM DB2 Connection Tutorial

I recently had the challenge of connecting to an IBM DB2 database via Unity. After some struggles with setting up DB2 and getting the user access all correct, it ended up being fairly easy. This quick tutorial will show you how to do it and point out some of the pitfalls you might encounter along the way.

Step 1 - Set up IBM DB2

To try this out you'll need to be able to connect to a DB2 database. I didn't have access to any so I set one up on my Windows 10 PC. Any of the DB2 installations should work fine for this, but for my task, I went with IBM DB2 Express-C. That's their free community edition. It's probably missing some more advanced features, but I really just needed a simple database set up to test the connection to. 

The installation isn't difficult, but the installer UI looks like something out of the 90s for Windows 3.1. Basically, just follow the prompts for the typical installation. You'll be asked to create a user and password. This actually creates a new user on the Windows OS. It wasn't clear that would happen at the time of installation and I probably could have gone with my standard Windows user credentials. This is an important factor to note. After setup this account that you choose is the one with default rights to create the database.

So after lots of digging around, I found out this was a problem I had and was slowing me down. Eventually, I found out that the Windows user you're logged in as has to belong to a user group that DB2 set up. It sets up two user groups: DB2ADMNS and DB2USERS. I made it so that my main Windows account belonged to both groups. This can be done via lusrmgr.msc. Right click on the Start Menu, select Run and type in lusrmgr.msc and you'll get the Local Users and Groups Manager window. In here you can select your username, right click to get to properties, then in the Member Of tab you can add the user to the user group. I think that only DB2ADMNS group is required, but I did both.

Once you get that all corrected you may also have to make some adjustments to DB2's configuration. This is done via the newly installed DB2 Command Window. I always run the Administrator version so that I'm sure I have all the access I need. Once you launch this you can run the command db2 get dbm cfg. This will print out the config details in the terminal window. If this doesn't work right away then try db2start, which starts the DB2 service. Now you'll want to change a few of these settings. specifically: SYSADM_GROUP, SYSCTRL_GROUP, SYS_MAINT_GROUP, and SYSMON_GROUP. You'll want all of these to be set to DB2ADMNS which is the user group in Windows that has full access to modify the database. Use the following command to set these:
db2 update dbm cfg using SYSADM_GROUP DB2ADMNS
Do this for each setting.

Now things should be pretty happy. You can try creating a new database with:
db2 create database YOURDATABASENAME AUTOMATIC STORAGE YES
If all is set up correctly then you should get a success message.

Other useful DB2 commands.

I don't overly enjoy working via the command line terminal so I went and downloaded IBM Data Studio. It was a pretty simple setup and I just went with the defaults. From there you can create your databases, tables, import data and run queries. One major annoyance I found with this is that when you type a lowercase name for a table or column name this program will surround it with double quotes. Which means that if you create a table named mytable then to query it you'll need to use "mytable" in your queries. Not cool, IBM, not cool. I eventually just named everything with caps, but Data Studio prepares SQL statements for you that you can edit and remove the unnecessary quotes when creating your tables. I still can't get Data Studio to create a database, so I do that by command line. Not sure what the problem is, I've even tried by running it as Administrator and even in the user account that it set up. No go. Command line, no problem. Go figure...

Also when you set up DB2 you have the option to create a sample database. My installation said this had failed, but after going in to Data Studio the database was present.

Last caveat: You'll need to make sure that your user has access privileges to the database. Do that in Data Studio via the database's properties.

Step 2 - Connect from Unity

Now that you have your DB2 installation all working fine (this took me what felt like forever) we can hop on over to Unity and set up access to the database. This part is pretty simple.

I created a fresh Unity project and added a Plugins folder to the project. We'll need to add two DLL files to this folder: 
System.Data.dll
System.EnterpriseServices.dll
Unity-friendly versions of these can be found in your Unity installation folder like this:
E:\Unity_5.3.4p5\Editor\Data\Mono\lib\mono\2.0

Of course, your directory will be different from mine, but the subdirectories should be the same. Just locate those two DLLs and drag and drop them into your project's plugin folder. I just left the settings on the marked for "Any Platform", but I've only tested on Windows so I'm not sure if these libraries will work on Mac or Linux. I highly doubt they will work on WebGL, maybe on Android, probably not on iOS (because what does? right?). 

Now that's all done we can finally get to my favorite part: code!
For a test I simply created a new MonoBehaviour class and attached it to an empty GameObject in my scene. The code below provides an example of making a simple query and reading the results as strings. For a real integration of this you'll want to convert the results to useable object types. A good example of this can be found here. For my purposes it was just good enough to prove a connection worked. And here's the code:


That's it. Hopefully the code is self-explanatory with all of the comments. I've set up a repository of this you can grab from GitHub that has a simple UI so you can do a full build and test it out on various machines or modify it to your own purposes. Check it out here.

I hope this saves someone from the many headaches I encountered over the past few days of trying to get this to work. There are a lot of outdated examples on the internet and none specific to Unity. Next up I have to test this with some other database management systems (DBMS) such as MySQL, SQLLite, Oracle, and SQL Server. Should be a fun time setting those up!



I was testing this for an additional feature of an app I'm working on called vuzop. It is a data visualization tool that allows you to view your data in 3D or with a VR headset. Check out more information on vuzop here.

As always,
Thanks for reading!


2016/07/22

Long Time, No See

Hi, everyone!

I noticed a blog post is way overdue. Please forgive me, I've been super busy.

"What have you been up to?" you ask.

Well, unfortunately, no new games from Napland Games itself (though I have many in the works), but I've been involved with a bunch of cool projects that have kept me quite busy.



My main project right now is called vuzop. It is a virtual reality data visualization tool. It can read in data from a database and create interactive visualizations where you can fly around to explore the data as it moves in real-time, sped up, or slowed down. It's target toward enterprise, but could be used in a variety of fields to explore data in a new and exciting way. You can see a demo video and more info at vuzop.com.



Another fun project I've been working on is Eddie The Yeti. A cute endless runner with beautiful Hannah-Barbera style characters. It's been released on Google Play, but we still have plans for more levels and features. Play it here.





I've also been spending all of my free time learning JavaScript and have completely revamped our website and merged in my portfolio page to a new, more modern and interactive site. It has videos, slideshows, crossfade slideshows, responsive navigation, and even a cool sound effect. I hope you dig it as much as I do! It's now easier to find some of my interactive portfolio pieces that you can play with right from your desktop browser. Check them out at naplandgames.com/services-game-dev.php, I think my favorite is the Model Exploder... or maybe Oh My Marbles (I swear I'll finish development someday!).

Beyond that, I've started focusing on tutoring Unity 3D a few months ago. I've had quite a few students making a variety of interesting projects. It's very cool to have a chance to see the ideas of fresh new developers. And it keeps me challenged and on my toes. Every session there seems to be a new challenge that I need to find a quick solution to. I'm really enjoying it. Soon I hope to offer group classes. The syllabus for the first 12-hour class is done, but there's still a bit of work to do!

In the meantime, I'm re-dedicating myself to writing blog posts on a more regular basis. It's easy to fall behind! I was writing for Clean Source Code, but unfortunately, the site owner could not continue to pay his dues and I did not have a chance to salvage my posts. And regrettably, the Way Back Machine didn't catch the site and archive it. So I've been a bit discouraged by that. Enough of my excuses. Expect more posts soon!

As always,
Thanks for reading!

2015/10/16

For the Love of Unity

As many of you might know, I've been switched over to Unity for a year now, almost exclusively. In the past year I've had the opportunity to work on a variety of projects as a freelancer. This has given me a chance to check out a few different development tools such as Game Maker Studio, Cocos2d, and Xamarin. Out of all of the packages I've tried none of them come close to Unity. It's clean, professional, stable, patched and updated to new tech frequently, easily extendable (the editor, Android/iOS plugins, etc), it easily ports to a bunch of different platforms, and there's a HUGE support community surrounding it. I can clearly see why it is one of the top game development tools. If you can't tell, I'm very happy with it.

Unity VS Toolbox is Born

Earlier this month I updated to Unity 5.2 which now comes with an installation of MS Visual Studio 2015 Community Edition (VS). I've been using VS 2013 for a while and built up some tools and templates in it, but they had become messy. So this gave me the opportunity to do some cleanup and build some other tools that I've been meaning to do. So I started a new public project on GitHub called Unity-VS-Toolbox. VS has the ability to create custom toolboxes. In this project I made a toolbox full of text snippets for each of the MonoBehaviour events. UnityVS Tools (the extension that connects Unity to VS) comes with something similar, an "Add MonoBehaviour Event" wizard. I always found this a bit clunky and it doesn't have the MonoBehaviour events in order of execution. My toolbox can be pinned open in VS and has the MonoBehaviours in order of execution. So, not only is it a functional way to add the event to your code, but it works as a quick reference too!

After making the toolbox I decided to keep going and share some of my other VS settings with the community. I've added text snippets for most of the MonoBehaviours and a few handy templates. The text snippets allow you to simply start typing the name of a MonoBehaviour event and Intellisense will automatically create a method stub for you. Unity VS does something similar via a hotkey, but I find this much more fluid. The templates I put up are pretty bare-boned at the moment. They include an editor script, scriptable object, the standard MonoBehaviour, a MonoBehaviour singleton pattern and a template of a MonoBehaviour singleton class. I hope to add more patterns as I find use for them in my games. I've just begun exploring programming patterns to help expand my programming knowledge and further speed up my development process.

Unity Design Patterns is Born

I also created a GitHub project called Unity-Design-Patterns. The goal of this project is for me to explore the various programming design patterns detailed in Robert Nystrom's Game Programming Patterns and make an example usage case in Unity. I feel this is a good way for me to learn more about design patterns and hopefully show other less-experienced developers a way they can be useful in Unity. So far I've only had a chance to explore the Command design pattern. It's pretty useful and one of it's main uses is that you can "record" and undo commands easily. It does have some caveats, though. You can read about these in the wiki page for the project. Next on the list is the Flyweight pattern. I'm having  difficult time finding a good example to make for this type of pattern since Unity handles a lot of heavy lifting like this in the background. I could skip to a Singleton pattern, but I want to be able to describe a solid specific example of when to use them so that I can debunk some of the hatred that surrounds them. This project is a lot of fun and a good challenge for me as it gets me to think more about structures. I'm already seeing that I use some patterns without really knowing what they are and I can now take this opportunity to define them in a better structure.

Other Unity stuff

Also on GitHub I have started posting Gists of some scripts that I make. One very useful script I put up is MasterCam. This script takes the settings of the main camera in the open scene and applies them to every main camera in every scene. It saved me a bunch of time in that project because we ended up changing camera settings many times. I'll be putting lots of useful scripts up there as a I come across ones I use or make that are general enough for community use. 

Finally, I've updated my Unity editor extension, Mobile Store Screenshot Helper, to be even more handy with a custom inspector that allows you to easily manage screenshot sizes (save and load to XML), and I improved the compatibility to be for Unity 4.6+. Last month we had great sales on the extension and I hope these improvements help to continue that trend.

In my next blog post I hope to tell you all about our next game. Right now I'm trying to decide between 2 prototypes. In the meantime I'm having a lot of fun "tinkering" with both.

As always, thanks for reading!

PS - I'm joining the team at CleanSourceCode.com as a blog contributor so I'll be writing more often and writing more about Unity there. Check us out on Facebook at facebook.com/cleansourcecode or on Twitter at @CleanSourceCode!

2015/10/01

Gravitone!


Finally, the day has come! Gravitone is now available on Google Play!

I apologize for all of the delays. I've been wrapped up in a number of client projects over the past few months and just haven't had the time to finalize Gravitone. After a short vacation I found some time to finish it up and I'm pretty happy with the gameplay.

Gravitone is an endless arcade style game that reacts to the music and has a simple goal: Push all of the orbs into the vortex that matches their color. However, things aren't that easy! The vortexes are shrinking and the orbs are not cooperative. Blue orbs are slow, white orbs are not, red orbs repel from their vortex, and green orbs spin. As soon as you get all of the orbs into their vortexes a whole bunch more pop out! Watch out for the Replicator that makes the orbs multiply. To help you groove your way to the top of the charts there are Time Stops, Vortex Expanders, Gravity Boosters, and Tractor Beams. The orbs and vortexes groove to tunes that you can select from your own music library.






Perhaps the most challenging part of this game was the player input (mobile input is hard!). I wanted it to feel like the orbs are alive and struggling against your finger, but not frustratingly difficult to push them around. After a ton of fine tuning I finally found a happy medium and I think it feels pretty good.

One of my goals with this game was to utilize Unity physics in a unique and abstract way that I'd never seen before while keeping the gameplay as simple as possible for mobile devices. All you have to do is push the orbs around with your fingers and tap on the powerup bar when you want to activate a powerup. It feels quite intuitive and is quick to learn.

Since the gameplay is typically pretty short (less than a couple of minutes). I wanted to give our players lots of reasons to come back. The game has leaderboards in Google Play and Facebook to encourage competitiveness and it also has a bunch of meaningful achievements. Almost all of our achievements are tied to unlocking a feature of the game. For example, if you get a score of over 500 you'll unlock the Vortex Expanders. I also provide the opportunity to unlock these by using coins you have collected by playing the game, watching video ads, or purchasing them directly from In App Purchases.


Next I have a bit of work to do before I can release it on iOS. Apple's push to have developers submit apps with 64-bit support means that we have a bit of work to do in updating the SDKs used in the game. I also need to write a plugin that will provide access to the music library on iOS and I'm not particularly looking forward to writing an Obj-C plugin.

At any rate, I hope that Gravitone is fun to play and that you find it is a unique gameplay experience. I had a lot of fun making it and I've learned a lot in the process.

As always, thanks for reading!

PS - Sudoku In Space t-shirts are now available! Check it out on Amazon!



2015/03/01

Adventures in Alternative App Markets Part 2

This is a continuation of a previous post which can be found here,

With Sudoku In Space we tried out many new things. Among them were multiple language support, a bit of paid advertisements, and distribution among various markets. Multiple language support was quite painful, but I think for Spanish it was well worth it as we have had some fair success in Spanish speaking countries. I'm not sure if our popularity in those countries is natural or more due to running a Chartboost campaign in those countries and they have a very low Cost Per Install. Japanese and Korean were not so much worth it. We've found that it is really difficult to break into those markets and I don't really think that Sudoku In Space is appealing to that demographic.

Our adventures in distribution turned out to be a mixed bag of results. For the most part the stores were pretty easy to publish on. There were a few exceptions which I mention in the previous post. In short, most were not worth the effort even as minimal as it was. The only one that stands out is SlideME. SlideME is one of the most popular markets we published on and they even gave us a featured spot which boosted our downloads quite a bit. Being featured by them is apparently pretty common, which is awesome because it gives many developers a fair chance at exposure. I'd highly suggest that an Android app is also published on this store. The effort was minimal and the return was pretty good.

On to the numbers!
I wanted to compare our results with those of Arturs Sosins as best as possible. I'm not sure if he was featured on SlideME so our numbers may be skewed in that way, but overall his app did much better than ours. It could be that it is more accessible as it is a casual game and not a puzzle game. Another major challenge was that AGK only supports IAP via the Google Play store. So we opted to publish 2 versions of the app on each store that blocked Google Play IAP. This was very painful and has led to 0 sales this way other that on Amazon. I have since tried to convince the developers of AGK to include OpenIAB support for Android which would give access to just about any IAP store. The numbers below are for the free version of the app only.

MarketsMonth 1Month 2Increase0%totalxGP
SlideMe377152(225)(60)%52948.09
GetJar011 1 10.09
Google Play7546(29)(39)%12111.00
Opera000 0 00.00
Socio FREE473 1 111.00
Amazon FREE077 7 70.64
Aptoide FREE341 0 70.64
Mobogenie10(1)(100)%10.09

As you can see, SlideME was by far the top market. Note that none of these markets had any paid advertising until after these dates. I'd also like to mention that these numbers are from Chartboost's recorded installs of our games and not from the sites themselves. Very early on we noticed a huge discrepancy between what the sites were reporting as downloads and what actually turned into installs. All of these markets were subject to this issue and I can only explain it as: There are bots clicking the download links. These markets have limited device ID tracking and don't seem to do a post install check, but only a link click. The other possibility is that users are downloading but not installing or cancelling. This seems pretty odd, especially for a game that was under 15MB at the time. There also could be things like download corruption and device compatibility issues. Ultimately we have no way of knowing, but we do know that what these store report is completely erroneous.

You may notice that this list is extremely trimmed from the previous blog post. So many markets were huge duds. They were riddled with download issues, only allowed payments via wire, were unresponsive to questions, etc, etc, I should also note that with Aptiode they offered us some free marketing credits, which was nice. Unfortunately, it turned out to equal about $1 per install and that was the only time we had installs through them. So if you're interested in pay about $1 CPI for non-guaranteed installs, that's the place for you...

Since this time we've done our first paid marketing campaigns with Chartboost. They all turned out just fine. We bid for $0.50 per install and that's what we paid. Most of the installs went to Spanish speaking countries because the bids there were lower on average, but if we wanted to wait we could likely have shut that off to focus more installs on the US / English speaking countries. Since the game is fully translated to Spanish, we didn't worry about this. We've had a lot of good reviews for the game and will still continue to work on making it visible, as that is the main problem (so many Sudoku games).

Sudoku In Space has just recently received coverage from NewsWatchTV.com. You can view their video review of the game here:

Also we're excited to announce that Sudoku In Space is one of Android Headline's top ten Sudoku games! Pretty sweet. I'm glad Allen is getting some attention and I hope this helps introduce Sudoku to many new people who wouldn't have tried the traditional grid and numbers style. The full article on that can be found here.

Soon I'll be talking about our next game, Gravitone. It is an arcade style game where you collect orbs by pushing them into their respective vortexes all the while the vortexes are shrinking and the dots are fighting against being put in their place. The whole game reacts to music and has some really interesting graphics. It is our first game with Unity and I'm having a great time using their tools. We'll finally have a game with all of the features we want like Facebook, Google Play, and Game Circle leaderboards and achievements, IAP in all of the markets with OpenIAB. We'll be able to share screenshots for bragging and all sorts of things we could never have done with AGK (without spending months extending its functionality and learning C++). We also hope to be able to publish this game as an online Facebook game. It should also be available via the web and if I can figure it out we can do Linux as well as Mac and PC, and maybe even Windows Phone 8. Stay tuned for more info on that.