This is when we make the collider really big on the coin. If the player gets in range of the collider then the coin moves like a magnet towards him. Which is kinda fun when there is lots of coins around and you feel like a millionaire just by standing around.
First of all – sorry about the misleading title – this post is about getting the doors working in the Endless Elevator game that we are currently developing. I thought it was a good pun and that as this post is all about our development process that it wasn’t too bad. The only career advice I got is just to start making games…any games.
You’d think making a door that opens and closes would be a pretty simple thing to do but surprisingly it wasn’t.
I designed and built some 3D models of building components in MagicaVoxel and exported them as .obj files. I use MagicaVoxel because it’s free and really quick and simple to use. When I model components I can be sure that they are all exactly the same scale and that all the different bits (no matter when I made them) are going to fit together without any hassle. But the models are not optimised for game engines as they have a reasonably high poly count due to the modelling process within the program. Most of the models come out with heaps of unnecessary triangles that need to be managed first. In most cases I will import the object into Blender and use the “decimate” modifier on the planes (with an angle of about 20 if you are interested). In the case of the door object it was pretty simple, it is just a door after all, and I didn’t need to optimise it.
Here is what the door looks like in MagicaVoxel:
Notice that the door object is sitting just forward of the enclosing frame and that when exporting the object the center is at the middle bottom plane of that frame. The door is off center because it’s modelled to fit exactly in a doorway that sits exactly in that position within the frame. This saves me a huge amount of time lining everything up when it gets to Unity as the position of the door (or any other object for that matter) is already in the right spot. The problem is that the point of origin for the door is in the wrong spot. It exports a few units behind the door and on the floor! This becomes important when you try and rotate that object (like you would when opening and closing a door) and the pivot point is not where the hinges should be.
To fix this I had to import the .obj file into Blender and reposition the point of origin for the model.
This is what it looks like in Blender when I did this:
To do it I selected the edge that I wanted the door to pivot on when opened.
Then in Edit Mode:
Mesh -> Snap -> Curser to Selected
In Object Mode:
Object -> Transform -> Origin to 3D Curser
So that puts the curser onto the correct position in the middle of that edge where the hinges would be and resets the point of origin (which is where it will pivot when rotated in Unity) to the right spot.
Once we were all imported into Unity and looking good I set up a prefab for the “Doorway” object with the door as a child object. The doorway object has a bunch of colliders to stop the player walking through the walls and a big sphere collider where the door would be to trigger the open / close function when the player walks into it.
This is what the doorway looks like in Unity:
Next I scripted up a few options for opening the door. I’ll post the script at the end of this article but basically there were three options of opening the door that I wanted to test. (Actually I tried it about six ways but whittled it down to the most simple methods – and just as an aside there is an actual “hinge” object type in Unity if you ever need it).
This is how the script looks in the editor:
Notice the slider at the bottom to control how far I want the door to open. It’s really handy to have this when playing in the editor and getting your settings right. If you want to know more about using it see this post
The three tick boxes are for testing the three different ways of opening the door.
Snappy was a quick simple transform of the position from open to closed with no “in betweening”. It looks a bit unnatural as the door magically goes from closed to open but it’s not too bad and most people are pretty used to similar behaviour in video games.
The active line in the code is:
the_door.transform.Rotate(-Vector3.up * 90 * Time.deltaTime);
The next method works more like a door should. In that it swings open and closed the whole way in a steady fashion. But the big problem with this method was that it was OK when the character was going into the doorway and with the swing of the door but when it was time to come back out of the doorway the door was in the way. There was not enough room to trigger the door opening from the other side without being hit by the door as it opened. Plus if the player enters the collider from the wrong trajectory the character gets pushed through a wall by the swinging door which is sub-optimal. I called this method InTheWay!
The active line here is:
the_door.transform.rotation = Quaternion.Euler(targetPositionOpen);
In an effort to combat this I chose to do a hybrid method that opened the door to a point that wouldn’t hit the player and then do the magic transform to get all the way open. I call this one aBitBoth. It looks a little weird too. Like there is an angry fairy pulling the door closed with a snap after the character enters.
Here are all three to compare.
In The Way
A Bit of Both
I’m not too sure which one I’m going to use at this stage as the Snappy method works best for now but I like the In The Way method better. I looks more normal and I like that you have to wait just a few milliseconds for the door to swing (adds tension when you are in a hurry to escape a bullet in the back). I could do something like halt the player movement from the rear of the door when it triggers to open from the closed side or maybe play around with the radius of the sphere. Neither solutions seem like great ideas to me right now but something like that will need to be done if I’m going to use that method. Maybe I could just have the door swing both ways and open to the outside when he is behind it but that’s probably a bit weird for a hotel door.
The Dog Run is an Endless Runner for Android that supports animal welfare!
It’s a free game. There is the option to watch ads but instead of in game rewards all profits from the advertising goes to support animal welfare and animal hospitals.
The game is about taking your fun lovin’ pooch for a run. But watch out! There is a bunch of obstacles in your path. It’s a good thing your dog is a natural jumper and can run all day in all sorts of weather.
We have been Beta Testing our soon to be released game The Dog Run and it’s been mostly OK but we had a number of issues with memory on smaller or older devices. We made some gains with modifying our audio files (See this post) but were still running into niggling crashes on start up and longer than normal load times.
We were getting feedback like:
“Hey, I installed the game and couldn’t run it. When I started it there was a black screen for about 15s and then it went back to the launcher. Then each time I went back to the game there was unity and game logo fading out and again the app crashed/hanged and I was sent back to the launcher.”
(Thanks slomoian and the_blanker for all your help testing)
Obviously feedback like this is a little disheartening and far from ideal. The game was running fine on every device and emulator I had access to but it’s only when you send something into the wild that you realise the full breadth of the spectrum that is the Android platform. I guess this is another lesson in the importance of proper Beta testing. One we hadn’t learned last time we released an app (see this old post on the perils and difficulty of finding Beta Testers).
We were using adb logcat to monitor our start up problems but not finding a “smoking gun” that solved every case. It seemed to be a memory problem and often with the graphics cache so again we went back to the Unity Editor build log to investigate our image files. The game uses multiple large files to ensure that our animated sprites were always in the right spot. The game is dependent on the titular Dog hitting the ground line accurately on every frame to achieve the look we wanted when he runs and the paw breaks the ground line and appears as a gap. We used a “flip-book” old fashioned style of animation where each frame sits exactly on top of the old frame and everything lines up on a transparency like in classic animated movies.
By using this schema we had to keep to a certain scale that fit within the constraints of a typical Android device format. This meant that when the images were imported the POT was not going to be something we could play with easily to get performance gains. (Image files that have a width and breadth that is a power of 2 are faster and easier for the compression functions to work with – so 2, 4, 8, 16, 32, 64, 128, etc). If I had the chance to do this again this is something I would probably start doing right from the beginning of development. When going through the Editor Logs we did find something interesting (get to the Editor Logs by right clicking on the arrow or tab near the Console and selecting it).
We found that some of our image files were 10 MB and a few were 2 MB. Which was a little weird as they were all exported as layers from the same Gimp file so I must have done something in the import settings or the editor to change them.
This is a comparison of two files of the same dimensions and basically the same content but with two very different file sizes:
10.6 mb 0.8% Assets/artwork/RunOnSpot6.png
2.0 mb 0.1% Assets/artwork/DogSitHeadWag.png
The difference that I found was MIP Maps. I’d selected to use MIP Maps fairly early on as it made the art work look smoother in the Editor. MIP Maps are generated in the engine to make smaller more compressed versions of your artwork that can be used at longer distances from the camera where the detail is less visible. My game is 2D and has everything running at pretty much the same distance from the screen so really MIP Maps should not be required. My art did look a bit better in the editor with them turned on but on a smaller device like a phone I couldn’t really tell the difference. See below the difference in a file with MIP Maps selected and a file without.
With MIP Maps turned on (see the file size at the bottom and that the type is RGBA 32 bit):
The same file with MIP Maps removed (down to 2 MB and using ECT2 compression):
This is the difference that generating those MIP Maps makes. Your file is converted from the Android default compression to a larger (harder to process) 32 bit compression format.
So by turning off MIP Maps across the three hundred plus image files in my game reduced my application start up time to under a few seconds and reduced the APK file size by over one thousand MB.
This is the Build Report from the Editor Logs that shows the larger texture sizes and final build size:
It’s a considerable difference with little or no quality loss on most devices. When I say most devices there were a few cases where the running dog did look a little tatty. On very small emulated devices (3.5″ screens and low memory) the images were being scaled down quite a lot and the results were a lot less enjoyable but still an acceptable compromise considering previously the game would not run on these devices at all.
The next thing I started playing with was the different texture compression variables available for Android. I tried all of the settings (see screenshot below) in a different build and tested them against at least ten different devices with various architectures and screen dimensions and Android versions.
In each of the cases but one there was at least one test device that failed to start the game. Once again exposing the issues of working with so many platform variables on Android. Even when I built the APK with the (default) ETC selected one device failed the start up test. So in the end the final build used the “Don’t override” setting which seemed to work on all devices.
Hopefully this is helpful to someone else out there and if it is try hitting the “Like” button below or sharing the link (the feedback keeps me going).
I found these references useful when troubleshooting my start up issues and learning more about compression on Android:
Let me say straight off that your first port of call for any Unity debugging should be the Unity Console.
Though sometimes you need more low level operating system logging for Android. This is where ADB (in lower case) comes in.
On Windows this is a command line tool to view the logs from a connected Android device.
The command line is not the only way to use the tool sometimes it’s better to use the Android Studio interface (a bit more graphical).
You will need to have your Android device connected to your workstation and USB debugging turned on (Google that if you need to). You could also use an Android emulator on your desktop.
I use Leapdroid or KoPlayer. (Leapdroid have now joined Google and no longer support the emulator but it’s still available to download on the internet). I guess you could also use the emulator that comes with Android Studio.
When your game is installed and running on your device go to the directory in your workstation (PC) where the Android SDK Tools are.
Should Google Manage Your Keys for Games built with Unity?
We recently had a problem that caused weeks of pain and struggle and it had nothing to do with coding. It was the damn java keystore signing process that we signed up for on the Google Play Store.
The basics are that the Google Play Store requires that all APKs be digitally signed with a certificate before they can be installed. Apps must use the same certificate in order for users to be able to install new versions or updates. This is a good and secure system. No issues here.
If you lose your key you cannot distribute any updates to your app/game. This would be really bad for some companies so Google offers to keep your keys safe so that you if you did lose them you can ask to have the key sent to you which gives you authority distribute again. Yay for Google!
But our problems start here in Unity when you build your game for Android the keystore is defined on the Player Settings tab of the Build Setting (CTRL+SHIFT+B).
In the first case when running your project from Unity the package (APK) is automatically signed with a debug certificate generated by the Android SDK tools. The debug keystore and certificate are in $HOME/.android/debug.keystore.
This debug certificate is insecure by design and can’t be used on the Google Play Store for publishing an Alpha release but you can upload it for Beta releases. I think this is where we started going wrong.
When you upload an APK to the Play Store you can opt in to app signing by Google Play. They recommend it but it’s optional. If you prefer, you can continue managing your own keys.
The advantages of opting in to the Google Play Store App Signing program is that 1. You ensure that the app signing key is not lost. 2. If your app signing key is compromised only a user with an account linked to your app can manage an upload key which makes it harder to do something malicious. (If you sign in your apps are signed with an upload key proving your credentials – Google then manages your APK and assigns it the correct and valid signing key).
To quote their documentation: “When using Google Play App Signing, you will use two keys: the app signing key and the upload key. Google manages and protects the app signing key for you, and you keep the upload key and use it to sign your apps for upload to the Google Play Store.
When you use Google Play App Signing, if you lose your upload key, or if it is compromised, you can contact Google to revoke your old upload key and generate a new one. Because your app signing key is secured by Google, you can continue to upload new versions of your app as updates to the original app, even if you change upload keys.
If you lose your keystore or think it may be compromised, app signing by Google Play makes it possible to request a reset to your upload key. If you’re not enrolled in app signing by Google Play and lose your keystore, you’ll need to publish a new app with a new package name.”
Alright. Read that last bit again. It’s important and why app signing might be a really good idea. If you manage your key yourself and you lose it and want to make an update to your app then you have to publish your whole app again under a different name. Again just to drum that home … If you lose your keystore, the only solution is to upload a new instance of the app to the Google Play Store with a new key, a whole new store listing like it’s a different product, as it will not accept an APK signed with a different key.
I was a little lost so I started looking for the help of my peers and of course from Unity.
I found a post from one poor soul who was in the same boat as me and the response from Unity Support was: “What do you want to be supported from Unity side? I see this unrelated to our build process.” So someone needs to have a little talk to that chap.
Look – and this is really the bottom line – it all got too frustrating and annoying trying to work out what the hell was going on and since I was only in my third release cycle I just opened up a new App on the Play Store and ditched the old one. But that’s just not possible for anyone who has an App out there and has no other option. So this is the process to getting that pesky key back.
In the Google Play Store you can see your App Signing Keys here:
You got your App signing certificate – this is the one that actually signs your app.
SHA-1 certificate fingerprint (above)
And your Upload certificate – this is the one that you use to upload with your APK so that Google knows it’s you.
Your upload key is only registered with Google and is used to authenticate the identity of the app creator.
Your upload key is removed from any uploaded APKs before being sent to users.
C:\Program Files\Java\jdk1.8.0_111\bin>keytool -genkey -v -keystore D:\ZuluOneZero\Demo-Unity-Android-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias Demo4Unity
Enter keystore password:
Re-enter new password:
What is your first and last name?
What is the name of your organizational unit?
What is the name of your organization?
What is the name of your City or Locality?
What is the name of your State or Province?
What is the two-letter country code for this unit?
Is CN=ZuluOneZero, OU=TheDogRun, O=ZuluOneZero, L=Melbourne, ST=Victoria, C=AU correct?
Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 days
for: CN=ZuluOneZero, OU=TheDogRun, O=ZuluOneZero, L=Melbourne, ST=Victoria, C=AU
Enter key password for <Demo4Unity>
(RETURN if same as keystore password):
Re-enter new password:
Note: keytool is located in the bin/ directory in your JDK. To locate your JDK from Android Studio, select File > Project Structure, and then click SDK Location and you will see the JDK location
(I used this one but you will have a keytool for every JDK and JRE on your machine – doesn’t matter which one you use)
Then, export the certificate for the new key to PEM format:
This is a quick demo of the basic play mechanics from our new game in development Endless Elevator. We got the basic movement working a while ago (see our Smooth Moves post) and now that The Dog Run is in BetaTesting we can spend some more time working on this game.
The Good Guy Cop Character movement (oh yeah he goes left and right)
Firing his awesomely powerful dumb dumb gun
Using (the eponymous) Elevator (see if you can spot the camera tracking bug!)
Traversing (the namesake) Escalators
Finally entering a doorway with a Power Cube (I’m not sure what it will look like in the final game yet). When he goes into a doorway with the special block the game flips and he goes into a Super Spy Store (not shown) where new fun weapons and power-ups are available! Cool.
One of the best ways to get noticed on the App Store (any one) is to have a video that markets your games best assets. We recently did one for NumBlocks which has, in all honesty, been struggling to make an impact on the Play Store. The game is elegantly simple and looks great. It has a good mechanic and is easy to learn and play. We built it as a platform to test our ability to publish something and to work through the hurdles of getting a game finished. In that respect it is perfect!
Have a go of NumBlocks and let us know what you think? (click image to Play)
Not having a huge budget for marketing we wanted to make it ourselves. Were not audio visual newbies and weren’t looking for anything too complex. Plus the game is free so there is really no point paying someone to effectively polish a lump of coal in the diamond that we know it is.
Here is the finished product (click to Play!):
We used the OpenShot Video Editor. Here at ZuluOneZero we support open source community driven projects as our default posture when looking for software to work with. OpenShot Video Editor is crafted with love and open-source. It’s under the free & open-source license forever (GPL version 3.0).
It’s very good and worked perfectly for our project. It has a simple but powerful interface and comes with a very nice set of built in transitions and other features.
We started off with a straight image of our NumBlocks logo. I really like the glowing internal light of this logo and the straightforward “Play” on the front. We did this icon in Gimp and imported it into the editor.
Check it out:
Next we got crafty. I asked the team (read ‘my brain’) for a flashing run through of the numbers in sequence to build tension and to lead in to the game play. We tried doing this manually in the editor but it was too fiddly lining up 40+ images with the right timing. So we came up with a novel solution and ended up opening all the number icon jpegs directly from the operating system folder onto the system picture viewer. We then used the built in Game Bar that comes with Windows 10 to record a screen capture of the viewer. I manually scrolled through the number icons with the arrow keys on the keyboard at the tempo I wanted and sped up to a crescendo at the end.
We used the record feature of the game bar again to record the game play sequences. This time we ran the app on a mobile emulator on the desktop. The only issue I had with the final outcome of this was that the mouse pointer has to be used and looks a bit derpy. Next time I’ll download a pointy finger mouse icon to use so it looks more like a mobile game. We edited the footage down to key sequences and game play.
Next I used the OpenShot speed manipulation tools to speed up a section of the game play footage to make it look more exciting and to showcase the game.
Next we stripped the audio from the existing clips and laid down some original music from the game. You can listed to the music here on SoundCloud.
P.S. If you want to be notified when I post please sign up and subscribe using the form at the lower right of the page.