Android App Promotion

Having released 9 android apps over the past few months and trying various methods of promotion along the way I thought I’d share my experiences with the various promotion methods I’ve used, and the results I’ve had from them.

The first few games I released, I didn’t do any promotion as such, except for posting on various forums descriptions of the games and links to the app store. These games predictably didn’t storm the charts and have plodded along at an average of around between 2 – 10 installs per week.

So more recently I decided to try to gain some extra exposure, and I used a couple of the services provided on https://www.fiverr.com/ where for a small fee $10 – $20 in my cases, my apps would be mentioned on blogs and Facebook pages that have hundreds of thousands of daily views.

Unfortunately I didn’t notice any increase in installs for the apps involve so I didn’t think these were worth the money spent.

 

APKFiles

The next service I looked at was a company called APKFiles www.apkfiles.com which lists free games on their site, with the option to pay and have your app stay at the top of the list.

For $10 dollars your app can stay at the top of the list for 200 downloads ($0.05 per download), so I signed up, uploaded my apk and paid my $10.00.

The site statistics quickly started counting up the downloads, and within 24 hours the whole 200 had completed. However, my analytics website showed no increase in new users or app activity, therefore I have to assume that either their site statistics are fake or wildly inaccurate, or that there is an appalling low download/install ratio.
In any event, I decided not to use APKFiles again and wouldn’t recommend them.

 

AdMob

For my latest game I decided to step it up and use create an AdMob campaign. On the face of it this looked like a good prospect. It’s a well known service, the pricing model is CPC (cost per click), and I could set a click cost as little as 1p per click and also a daily maximum budget. There was no up front payment required, and no minimum length of time for the campaign to run.
So I went ahead and created a campaign to run for a month, at 1p per click and a £5.00 budget per day (500 clicks per day), which I thought sounded reasonable, assuming I hit my maximum budget every day the whole campaign would cost around £150.00.
Results went as follows:-

Day 1
32265 ad impressions before I hit my 500 click daily limit, took about 30 minutes.
App installs 12

Day 2
31156 ad impressions before I hit my 500 click daily limit, took about 30 minutes again.
App installs 5

Day 3
34156 ad impressions before I hit my 500 click daily limit, once again took about 30 minutes.
App installs 7

So after 3 days, I’d had 24 installs total, at a cost of £15.00, meaning each install was costing me £0.63. Not exactly the result I was hoping for. I can only assume that the vast amount of clicks on my ad were not from people that were interested in installing my game, and that AdMob doesn’t do a very good job of filtering out accidental clicks.
Anyway, at this point I decided that a cost per click promotion wasn’t going to work out cost effective for me and I suspended my AdMob campaign.

 

AppBrain

Still in search of an effective promotion method, I did some Googling and found a number of posts that mentioned a cost per install service run by a company called AppBrain.

With this service you pay a minimum of $0.20 (approx. 14p) per install, irrespective of the number of impressions your ad has.

You need to credit your account in advance (min $100, approx. £72.00), which due to the good reports I’d read I decided was worth the risk, at $0.20 this will give a guaranteed 500 installs by the time your $100 budget is used. You can set your daily limit to be a percentage of your whole budget, or leave it unlimited to get as many installs per day as possible.
This all sounded good, so I set my daily budget to the whole $100 campaign budget, and waited to see what happened.
The difference compared to AdMob was, to say the least, astounding, within minutes I had thousands of ad impressions, hundreds of clicks and 20-30 installs, already eclipsing the 3 day AdMob campaign.

Results were as follows:-
Day 1
672,343 Impressions, 9573 clicks
App Installs 500

This was much more along the lines I was expecting, and if anything it generated installs at a faster rate than I was expecting based on my minimum bid of $0.20 for my ad campaign.
The daily install rate continuing on from then is up around 30 – 40 per day, which easily eclipses the 1-2 per day that I usually get, so the initial ad campaign seems to have boosted the performance going forward too.

So to sum up, out of the methods I have used AppBrain was by far the best, and whilst I still haven’t produced the million seller I’m after, it still represents, to my mind at least, pretty good value for money and is the best way I’ve found to promote my apps so far.

In addition to the promotion service they also do a monetization service through ads, which I haven’t tried yet, plus you can track the store rating for your apps in all the countries it has been downloaded. All in all a pretty decent service.

If you want to try this service out for yourself you can find it here http://www.appbrain.com

My latest game Cubeology can be found here if you want to take a look.

Cubeology Released

Released our latest game today, Cubeology.

Get it on the Play Store

Unity web player version available here

Cubeology is a 3D picture cube matching game in which you select pairs of cubes with matching designs to remove them, until there are no cubes left.

It has 5 different game types, which can be played in either a cube layout or a sphere layout, with either free or fixed rotation, making for 18 game variations in total.

It has separate Google Play leaderboards for each of the 5 different game types.

Colourful graphics, catchy soundtrack and addictive gameplay make this a fun game that you keep coming back to time after time.

Standard Game
———————
Select pairs of matching cubes until there are none left. Earn extra points by matching multiple pairs in quick succession. No time limit.

Timed GameImage3
——————
Select pairs of matching cubes until there are none left. Initially there is a 15 minute time limit in which to finish the cube. The time limit decreases by 30 seconds every time you successfully complete a game, or it increases by 30 seconds if you fail to complete the game in time.

Speed Cube
—————–
A fast paced game with a smaller 3×3 cube block and a 30 second time limit. How quickly can you clear the cubes, quick thinking and fast reactions will be required to top the leaderboard.

Cube Builder
——————
The idea of this game is different in that you start off with just a few cubes and more are added as time goes by. The rate that cubes are added increases as time passes and the game is over when the block is fully rebuilt. Your goal in this game is to keep the block from being completed as long as possible and in doing so earn as many points as you can. As in the standard game extra points are awarded for matching pairs in quick succession.

Picture Search
——————–
This is a memory version of the standard game, in which all the designs are hidden and are only revealed when you click on the cubes. If you select two cubes that match they are removed as usual, otherwise the pictures are hidden again.

In all versions of the game that award points, making incorrect matches will deduct some points.

Scene Transition/Screen Fader Tutorial Part 2

Welcome to part two of my screen fader tutorial. In this part I will provide a short demonstration of how you might use the screen fader to smoothly transition between scenes.

I’ll add two scenes to the project, with different title text and background colour, so it’s obvious when the scene has changed, and a single button in the middle of the screen which will be used to make the scene change.

I’ve added a small script to the button, which exposes an Object property to the editor, into which I drag the scene that I would like the button to load when clicked. Note: any scenes that are to be loaded at runtime must be added to the build settings in the editor.
Build Settings

This button script is how an inexperienced Unity programmer might approach it, but it won’t work properly and if you try it you’ll see that the scene change happens immediately with no fade in or out.

The reason for that is that as soon as the fade out function is called Unity moves immediately onto the next line of code and executes it, this stops the fade out and loads the next scene. It then goes on to start the fade in function, which has no effect as the screen isn’t faded out.

So how do we prevent execution of the line after the fade out call until we are ready for it? One way would be with coroutines, but this can easily get messy and means that we can’t keep all our code in one function. So this is where the callback argument of the fadein/fadeout functions comes into play.

With the above in mind we could write our button code like this instead:-

So now we have separated the fadeout function call from the load scene and fadein function calls, and put them in a separate function. We have then provided the new function as the callback argument for the fadeout routine.

Now if you run the program and click the button you’ll see that it works exactly as it should, the original screen fades out, and then the new scene smoothly fades into view.
This is because now the fadeout routine is executing and only when it’s finished does it invoke the callback function which loads the new scene and fades it back in.

This is much better, in as much as it actually works. However earlier I mentioned that a disadvantage of using coroutines to achieve the same was that we couldn’t contain everything in one function, and you’ll probably have noticed by now that this solution suffers from the same problem.

We can fix that however by writing the callback function inline in the fadout function call, this isn’t strictly speaking necessary, but in a lot of instances it can keep the code simpler and easier to follow in my opinion.

So this is the final version of the button script:-

As you can see the whole process is now contained within a single 7 line script, with execution of the scene change and fadein delayed until the fadeout function has finished. I’ve also added a 0.5f second delay to the fadein function call as I think it looks better with a slight extra delay.

That’s it for this tutorial, as always any and all comments or suggestions are welcome. See you next time.

Unity project file

Scene Transition/Screen Fader Tutorial Part1

A common feature of games is that the screen briefly fades to black during scene changes. This is done to ‘soften’ the transition as a sudden switch from one scene to another can be a bit jarring if it’s visible when it happens.

So I’ve found it handy to have a screen fader that I can easily drop in to a new project any time I want to have fade to black (or some other colour) scene transitions and I decided that it would be a nice subject for a mini tutorial. It will also serve to demonstrate a couple of seemingly often overlooked but very useful features, i.e. callbacks and CanvasGroups.

The aim of this tutorial will be to provide a screen fader that is fairly simple to implement and is also flexible and easy to use.

The way this screen fader will work is by overlaying a UI image on the screen and changing it’s alpha value to fade it in and out.

To make it as easy as possible to add to a project, we’ll have the fader create its own UI elements in code, which means all we have to do is drop the screen fader script onto an empty game objet to make it available for us to use. To make this work we’ll need the screen fader to create its own Canvas, CanvasGroup component and an Image.

Step 1)
This is the code to create the Canvas at runtime:-

What this does is create a new GameObject with a Canvas component attached. It then parents it to the GameObject that script is on, then it sets the RenderMode to ScreenSpace overlay and sets the sort order to the value specified in the inspector (default 99). I have made the sort order easy to change so that you can make sure the fader image is always on top of everything else. However depending on what you wanted you could also use the sort order to have it appear behind some elements.)

Step 2)
This is the code to create the CanvasGroup at runtime:-

We use AddComponent() to add the CanvasGroup component to the canvas we just created, and then store, in a member variable, the reference to the component that it returns for later use. Then we set interactable and blocksraycasts to false, which means that any child objects of the canvas group won’t block mouse clicks. This isn’t strictly necessary for our purposes here, and indeed in some instances you may want your screen fader to block input, in which case you would set interactable and blocksraycasts to true.
Lastly we disable the GameObject as we don’t need to have it enabled until we are ready to use it.

Step 3)
This is the code to create the Image at runtime:-

Firstly we create a new GameObject with an Image Component attached, then we set it as a child of the canvas we created in step 1. Next we set its colour to the value specified in the inspector (default black), and lastly scale it up a bit, this last bit is done to prevent a slight border appearing around the edges in some screen resolutions.

Step 4)
Set the image position and size and make it scale with the screen size:-

The easiest way to change position and size of ScreenSpace UI elements is to use the RectTransform component, so firstly we get a reference to the Image RectTransform using GetComponent().

Next we set the anchors to the bottom left and top right to make the image stretch with the screen size. The anchors are Vector2s with values between 0,0 and 1,1, where 0,0 is the bottom left of the screen and 1,1 is the top right of the screen.
Next we centre the image by setting its anchoredPosition to 0,0;
Lastly we set the width and height to match the current screen size (due to the scaling we did in step 3, it will be slightly larger than the screen).

Now we need to put all of that above into the Awake function of the screen saver. This is the complete Awake() function.

The only part of the Awake() function I haven’t discussed yet is the very first block of code. Basically what this does is make the screen fader not get destroyed during scene changes, and also ensures that the only instance of it that can exist is the first one that is created. It also grabs a static reference to the first instance so that it is possible to access non static methods and properties.

That’s the basic setup finished, so next we’ll define a couple of static methods that will enable us to perform fade outs and fade ins. The methods will invoke callbacks when finished so that we can delay execution of other code whilst the fader is in operation. We will also be able to specify a delay before and/or after the screen fade.

This is the public static method to do a fade out:-

As you can see it is quite simple, all it does is check to see if the callback argument is null, and if so it points it to the default empty callback function and then it sets the canvas active.
Next it stops any current fade in/out operations (I’ll discuss that function further on) and runs the fade out coroutine, which is where most of the work is done.
It uses the variant of StartCoroutine that returns a CoRoutine object, which we store for use by the StopActiveFades() function.

This is the code for the fade out coroutine:-

There again, this is quite straightforward, first of all we yield wait for the delayBefore period.
Then we loop while the group.alpha property is less then 1. The alpha property controls the transparency of all children of the group (in this instance our image we created in step 3), a value of zero means fully transparent and a value of one means fully opaque.

In the while loop we use MathF.MoveTowards to linearly fade from transparent to opaque, we can use the speed property in the inspector to control how quickly this happens.
After the while loop exits we yield wait for the delayAfter period if any, and then we invoke the callback to signal that the fade is done.

The fade in functions are almost identical, except in the while loop we change the group.alpha from one to zero and when it’s finished it disables the canvas.

Now let’s take a look at the StopActiveFades() function:-

This function just ensures that there can’t be two fade operations running at the same time, as that could result in unwanted behaviour.
What it does is check the fadeInCR and fadeOutCR variables and if they aren’t null it stops the coroutine they point to and sets the variable to null.

Last of all is the default empty callback function, which doesn’t need any explanation.

In the next part of this tutorial I will show how we can use the screen fader in our applications, but in the meantime here is the full screen fader script:-

As always any and all comments are welcome, see you next time.

Tetriks Cube

Just released the Android version of our Ludum Dare #35 game jam entry, Tetriks Cube.

Tetriks Cube is a kind of fusion of Rubik’s cube, Tetris and Hole In The Wall.

The aim of the game is to get your cube to pass through as many walls as possible by rotating the cube so that the coloured blocks facing you line up with the coloured hole in the approaching walls. Get it lined up properly and you destroy the wall and score points, get it wrong and the wall destroys you and it’s game over.

As you progress the speed you move increases, giving you less and less time to react. How many walls can you negotiate on hard difficulty?

There are three levels of difficultly, the higher the difficulty the faster your cube moves at the start of the game. But you score more points per wall as a reward.

There are separate Google Play Game Services leaderboards for each difficulty level and various achievements to unlock. Are you skilled enough to be the top scorer?

The simple swipe control system makes this an easy game to pick up, but it will require quick thinking and fast reactions to stay at the top of the leaderboard.

Google Play Store Page

Feature Graphic

 

UNET Tutorials

Sadly due to the current state of UNET, specifically the number of bugs and inconsistencies it suffers from, I have decided to abandon my series of networking tutorials for it for the time being.

This has been prompted by the discovery that my simple MatchMaker based project, which I was writing to demonstrate a custom network manager and HUD, disconnects clients after around 15 seconds due to a bug in UNET (which I have reported, tracker no. 794106). There are also further bugs and omissions in the Matchmaker system that make it difficult to produce a clean and reliable end user experience at the moment.

Consequently I have begun work converting my previous UNET tutorial series to Photon PUN and all further networking tutorials will be based on the same.

Once UNET is more stable I may consider carrying on with tutorials for it, however I think this won’t be likely in the near future.

In case anyone is interested though, here is a link to the abandoned Unity Project I was working on, and these are the scripts, hopefully they may prove to be of use to someone.

Generic Serialiser Class

It’s been a busy month what with one thing and another, so I haven’t managed to get finished the UNET custom NetworkHUD tutorial I’ve been working on, but I’ll post it as soon as I can.

In the meantime I’ve been doing some groundwork for an RPG idea we’ve had, and one of the first requirements is for an easy way to save and load the state of the various data classes we’ll be using. As this is something that also seems to get asked for on a fairly regular basis in the forums, I thought I’d share what I’ve come up with so far as it might prove useful to others in some situations.

The serialiser as it currently stands is quite simple, it has four static methods, two for serialising the data (one to PlayerPrefs and one as binary data), and two that read in the data and return it in an instance of the corresponding class.
It will serialise any class or struct that is marked as Serialisable and it even works with dictionaries.

This is the code for the serialiser class.

As an example, to save the state of a class to PlayerPrefs you would use something like this:-

To load the data back into the program you would use something like this:-

The way I actually tend to use it though is to wrap the serialiser calls into two methods on the class I want to serialise. An instance method for saving, and a static method for loading the data, which returns an instance of the class populated with the data.

So for example, i might define a PlayerInfo class something like this:-

And then from elsewhere in the program I would load and save the class data like so:-

The Load() function automatically handles the situation where there is no saved data yet, and returns a new instance of the class in that case.

I have made a simple demonstration program that allows you to type in a player name and add and remove items from the inventory. When you exit and restart the program you will see that the changes you made will have been preserved.

Using this generic serialiser it becomes a simple task to save and load even quite complex classes and structs, as long as you remember to mark them as serialisable.

Also remember that if you make any changes to the serialised class definition after you have saved it, you will most likely have to delete the saved data to avoid errors when it tries to load it next.

I hope this proves to be of use to someone, and as always any comments and suggestions are welcome.

You can try out the test program in a Unity WebPlayer here or download the project files here.

See you soon

Martin.

Arcade Style Bouncy Vehicle Physics Tutorial

What is this tutorial?
In this tutorial we will look at how to set up arcade style vehicle physics on a 3D model. As with my previous tutorial, in an attempt to keep it as clear and concise as possible I will keep the game design quite simple, therefore this should be seen as a basis from which to build a game, rather than a tutorial for a complete and finished game.

Who is this tutorial aimed at?
This is aimed at people with a reasonable knowledge of C# and Unity as I won’t be explaining in depth basic C# programming concepts or basic Unity concepts, unless it is appropriate to do so within the scope of the tutorial.

Part 1 – The vehicle game object

 As this is a tutorial on coding rather than building game objects in the editor, I’m not going to give step by step instructions on how to put together the car and terrain, instead I’ll just give a brief description of the important bits and how they relate to the code, and I’ll provide all assets in a download link at the end of the tutorial.

First of all I should point out that the method we will be using isn’t a realistic physics simulation, instead it uses forces to ‘fake’ the physics, but the outcome is reasonable and gives a nice Mario Kart style feel to the vehicle handling.

The way we’ll achieve this is by firing a raycast down from each corner of  the vehicle a certain distance (hoverheight), and if it detects a hit, it adds an upward force. We also adjust the strength of the upward force depending on the distance from the vehicle that the raycast detects the hit. So effectively the closer the vehicle gets to the ground the stronger it is pushed back away from it, and vice versa.

The length of the ray we fire can be adjusted, and the longer it is the further the vehicle will float above the ground, we will be using a fairly short ray, because we want this to appear as if it is actually on the ground. However by increasing the hoverheight and hoverforce you can simulate a nice hover car type behaviour instead.

This is a very basic example of how we would set up the vehicle game object with the hover points. The red circles indicate where the hover points are positioned. Notice that they are placed vertically above the centre of the vehicle, this is because of the way we simulate gravity in our code, as I’ll explain a bit further on.

HoverCarBasic

We’ll also attach a rigidbody component, and for this example we’ll give it a mass of 70, drag 3 and angular drag 4. These figures work quite well as they are, but you can achieve different handling effects by tweaking them also.
Lastly we give it a box collider to detect collisions with other scene objects and also to prevent the vehicle from falling through the terrain when the downward velocity is very high and we’ll put it on its own layer (vehicle), so we can ignore it in the raycasts.
We’ll also untick Use Gravity, as we will be handling gravity ourselves.

So that’s pretty much all that’s needed for a basic vehicle setup (in the finished project I have added a buggy model which looks a bit nicer than a plain cube).

Part 2 – The code

So now let’s take a look at the code that will turn this into something a bit more interesting. First off we’ll add the various properties that we’ll use to control the behaviour of the buggy as so.


Most of this should be pretty self explanatory, but I’ll explain what some of them do.

The deadZone value is just a way to make the controller not so sensitive to small movements. Basically any input below the deadZone threshold is ignored.

The groundedDrag value is used to change the buggy RigidBody drag factor depending on whether the buggy is grounded or in the air.

The dustTrails array will hold references to the particle systems that play when the wheels are grounded.

The layerMask property is used to prevent the hover point raycasts from registering hits on the buggy.

Next we have the Start function, which stores a reference to the buggy Rigidbody and stores a reference to the inverse of its LayerMask, for use in the Raycast later.
It also sets the Rigidbody.centerOfMass to be one unit below the buggy, this helps to keep it a bit more stable when it’s in the air.

In the Update function we read the current input and assign a value to the acceleration and rotation from it.

Most of the work is done in FixedUpdate, so let’s take a look at this one bit at a time:-

This block of code above handles the hover/bounce behaviour.
To start with it clears the grounded flag.
Then, for each of the hover points, it fires a raycast of hoverHeight length downwards, and if it detects a hit it applies a force in the opposite direction and scales it depending on the distance the hover point is away from the hit point. So the closer the hover point is to the point which the ray cast hits, the greater the force that is applied to push it back. Kind of like what happens when you compress a spring.
Grounded is also set to true if any of the raycasts detect a hit.

If, however the hover point raycast doesn’t detect a hit, then that means this wheel/corner of the vehicle is off the ground, so we need to handle this differently as follows.

It compares the y position of each hover point with the y position of the vehicle, and pushes it up if it’s below it, or down if it’s above it. This serves two purposes, firstly it makes the vehicle automatically level out when it’s in the air, and secondly it applies a fake gravity effect. This is why the hover points need to be positioned above the centre of the vehicle transform, so that when the vehicle is in the air it will be pushed back down by the gravityForce amount. If we positioned the hover points below the y position of the vehicle transform, once it left the ground it would fly up into the air and never come down.

The next section of code handles other behaviour differences between when the vehicle is grounded and when it is airborne.

So basically, if the vehicle is on the ground, we set the Rigidbody.drag value to the amount we set in the inspector, and we give the dust trail particles a suitable emission rate.
But if the vehicle is in the air we set the Rigidbody.drag to a very low value, and we also drastically reduce the thrust and turn values, as we don’t want to have full control whilst we aren’t on the ground.
Lastly for this section, we iterate through the dustTrails array and set the particle emissionRate to the appropriate value (10 if grounded, zero if in the air).

Last of all we apply the thrust and turn forces to the vehicle and then limit it’s velocity to the maxVelocity value we set in the inspector.

So that’s the entire vehicle controller script, it produces quite a nice arcade style drive and with a bit more work could form the basis of a fun driving game, you can test out the complete project which can be downloaded from here. Once you have loaded it into Unity you will need to open Assets\Scene 1.

The behaviour of the vehicle can be modified to make it feel like it’s driving on different surfaces by changing the various properties exposed in the inspector, for example to make it feel like it’s on ice change the following properties:-

  • Grounded Drag = 0.5
  • Max Velocity = 30
  • Forward Acceleration = 1500
  • Reverse Acceleration = 750
  • Turn Strength = 500

It uses the standard WASD and Arrow keys to control acceleration, braking and turning.

Thanks to Carbon Concept for the free buggy model

I hope you enjoyed this tutorial, and please feel free to post any comments or suggestions.

Download project files