Saturday, April 26, 2014

Custom Loading Screens in Unity3d

Since releasing my game, No Girls Allowed, I've had some people ask me how I created the custom loading screens in it. If you've played the game, you've probably noticed that whenever you start a level, you come across a different loading/tip screen. Instead of having to keep explaining it to people, I've decided to just create a little tutorial about it that I can simply point everyone to. As an added bonus, I'm also going to (very briefly) touch on coroutines and scaling the GUI to make content look the same across different screen sizes and resolutions.

Keep in mind that I'm not claiming to be an expert on the subject in any way. I've just had some people ask me about this, and decided to share what I did in my game. Hopefully this can help save some of you time so you can spend it on more fun stuff in your own games. In fact, if you want to save a bunch of time and take the easy way out, I've zipped up the scripts and linked to them at the bottom of this tutorial. So with all that in mind, let's get going.

Setting Stuff Up

To get started, here are a couple of loading images you can use if you'd like:

This is going to be a pretty quick and easy tutorial, so these will be the only image assets we need. Go ahead and place them wherever you keep your textures - for me, that's right in the Resources folder. The first thing we're going to do inside of Unity is create a couple of scenes. I just called mine "Scene1" and "Scene2" to keep it simple. Next, add a couple of scripts, and let's name them "Scene1_Script" and "Scene2_Script". These will be attached to the main camera in each respective scene. Also, don't forget to add both scenes to the build settings - otherwise you won't be able to build. Alrighty, now it's time to get to the code.

Scene 1 Script

The high-level goal of Scene1_Script is to pick a random load screen, save it in our PlayerPrefs, slide it in, and load the next scene. To begin, let's set up the variables we'll be using.
Texture loadScreen; //Main Texture used for load screen
float randomLoadScreen; //Random float to determine which texture to use
float loadY = -720.0f; //Load screen Y Position
bool slidingLoadScreenIn; //Whether it's sliding in
Alright, now let's do something with this stuff. We'll start by creating our method to randomize the loading screen. Let's call it "PickRandomScreen". In here, we'll pick a random float between 0 and 1, and set our loading screen to Loading1 if it's below 0.5, and Loading2 if it's above it. We'll also need to save the results to PlayerPrefs. It should look like this:
void PickRandomScreen(){
 randomLoadScreen = Random.Range (0,1.0f);
 if(randomLoadScreen <= 0.5f){
  loadScreen = (Texture)Resources.Load ("Loading1");
  PlayerPrefs.SetString("LoadingImage", "Loading1");
 }
 else{
  loadScreen = (Texture)Resources.Load ("Loading2");
  PlayerPrefs.SetString("LoadingImage", "Loading2");
 }
}
Alright, since this is the first thing we want to do, let's go ahead and call it in our Start method.
void Start () {
 PickRandomScreen();
}
Now that we've selected our loading image, we want to use it. Since this is just a tutorial, we'll just load Scene2 by clicking a button. Let's add this to the OnGUI method:
if(GUI.Button(new Rect(20, 20, 200, 50), "Load Next Scene")){
 slidingLoadScreenIn = true;
}
Alright, now we need to draw the actual loading screen to the OnGUI method and position it. It's going to start just off the screen, and when slidingLoadScreenIn is active it will slide in to cover it. It should look like this:
GUI.DrawTexture(new Rect(0, loadY, 1280.0f, 720.0f), loadScreen, ScaleMode.ScaleToFit, true, 1.78f);

if(slidingLoadScreenIn){
 if(loadY < 0){
  loadY += 10.0f; //Increment up to slide load screen in
 }else{ //All done - load screen is in place
  slidingLoadScreenIn = false; //Stop lowering screen
  Application.LoadLevel ("Scene2"); //Load next scene
 }
}
If you build it, you should be able to click the button and see the load screen slide down, now. However, you'll see that it might not cover the whole screen. To fix this, we need to adjust the Matrix to format everything to fit in our native size. I made the images 1280x720, so that's what we'll use.

Declare these along with the rest of your variables in the beginning of the file:
float native_width = 1280.0f;
float native_height = 720.0f;
float rx;
float ry;
Throw this in the top of your OnGUI method:
rx = Screen.width / native_width;
ry = Screen.height / native_height;
GUI.matrix = Matrix4x4.TRS(new Vector3(0,0,0), Quaternion.identity, new Vector3(rx,ry,1));
Alrighty, now everything should be scaled properly and the loading screen should come on down when we click the button. That should be all we need for Scene1_Script. Good job, everyone! Now go take a food or potty break and be back in 10.

Scene 2 Script

Back already? K, well, let's get going on the rest of our project. The next thing we need to do is set up Scene2_Script to get the loading screen, simulate pulling in some resources, and then dismiss the loading screen. Here are the variables for this script:
//Setting up values for Matrix
float native_width = 1280.0f;
float native_height = 720.0f;
float rx;
float ry;

Texture loadScreen;
float loadY = 0.0f;
bool slidingLoadScreenOut;
bool allDone;
The first thing we need Scene2_Script to do is get the loading screen that was randomly picked in the other script. If you remember, we saved it to PlayerPrefs after we set it. Now you know why. We're going to create this method and call it in our Start method:
void GetLoadScreen(){
 loadScreen = (Texture)Resources.Load (PlayerPrefs.GetString("LoadingImage"));
}
So, the whole reason for loading screens is in the name - to load stuff for the level. Since this is a really simple little project with nothing else to load, we're going to just set up a coroutine to wait for a few seconds to simulate the loading of assets. Deal? Deal. After the time has elapsed we set the slidingLoadScreenOut boolean to true to trigger the sliding out. We'll write out a couple things to the console to make sure it's doing what we want it to.
IEnumerator DoStuff1(){
 Debug.Log ("Waiting 3 seconds to simulate loading...");
 yield return new WaitForSeconds(3.0f); //Wait for 3 seconds
 Debug.Log ("K, that's good.");
 slidingLoadScreenOut = true; //Send the loading screen back up
}
To start this coroutine, we'll place this in the Start method:
StartCoroutine(DoStuff1());
Alright, now before this will do anything, just like in the first script, we'll need to actually draw the loading screen in the GUI. We'll start with setting up the Matrix, just like we did earlier, then draw the texture, and slide it out based on the slidingLoadScreenOut boolean. The last thing we'll be adding here is a little label that will appear when we're all done and the loading texture is out of the picture.
//Matrix Stuff
rx = Screen.width / native_width;
ry = Screen.height / native_height;
GUI.matrix = Matrix4x4.TRS(new Vector3(0,0,0), Quaternion.identity, new Vector3(rx,ry,1));
  
GUI.DrawTexture(new Rect(0, loadY, 1280.0f, 720.0f), loadScreen, ScaleMode.ScaleToFit, true, 1.78f);

if(slidingLoadScreenOut){
 if(loadY > -720.0f){
  loadY -= 10.0f;
 }else{
  slidingLoadScreenOut = false;
  allDone = true;
 }
}
if(allDone){
 GUI.Label (new Rect(500, 300, 200, 50), "Hey, we did it!");
}
*One thing to note: You will always want to make the loading screen the last object in the OnGUI method. This is because the method works by layering the later objects on top of the previous ones.

As promised, here are the zipped up scripts for your shortcut-taking pleasure.

Well, that's about all I've got for you guys. If you have any questions or suggestions, feel free to let me know in the comments. Also, be sure to follow my blog if you're interested in more of these little tidbits, because I'll try to add more here and there as I come across them. Thanks for indulging me, everyone!

Friday, March 14, 2014

My First Game: From Conception to Completion



So...what do you think? Holy cow, the last 3 years have been crazy for me. I've been busy raising a family (2 boys - 2 and 4 years old), teaching myself development, getting my business degree, and most importantly (well, as far as this blog is concerned), creating and releasing a brand-spanking new Android game. The journey has definitely had its ups and downs, but I'm so glad I was able to stick to it, because seeing my creation on the Play Store is one of the coolest things I've done with my life. Thank goodness I have an incredibly patient wife and kids, because they haven't gotten nearly as much attention as they've deserved during this process. Anywho, my goal for this blog post is give everyone an idea of what it took to create and release my first game, No Girls Allowed. Disclaimer: I am in no way, shape, or form claiming to be an expert on the subject matter - this is simply my story of turning a fun little idea into a playable game.

Everyone has a Game Idea

Let's be honest - almost everybody has had some sort of video game idea. Some people want to make a 10,000 hour fantasy RPG, while some just want to see how many pipes they can squeeze a bird through before smashing into them (my high is 65). Some of the ideas are great, some are really lame (sorry, but they are), and most are somewhere in between. No matter how amazing these ideas may be, we all know that a good 99% of them will never turn into anything more than sketches we made in our notebooks during math class. Personally, I sketched out enough characters for probably 100 games (or maybe just one huge ridiculous ADHD-riddled game) during my school days. However, like most people, I had no idea how to turn these ideas into actual games. That was then. Luckily, in my later years, I was able to learn how to do exactly that.

Getting Started with Development

So, a little over 4 years ago I was given an amazing opportunity to learn web development on the job. My brother was a web developer at a small company, while I was working as a helpdesk technician at the Flying J headquarters. He told me that I was in something of a dead-end job (which actually became true as they declared bankruptcy within the next few months) and that I needed to come work with him developing websites. I had taught myself a little front-end web development on the side (incredibly basic stuff, like putting a couple divs on a page or alerting "Hello World!"), but that was the extent of my experience. If I were to take him up on it, I knew that I would be really, really green. I hesitantly agreed to go to an interview, thinking that there was no way I'd be getting the job. Lucky for me, his boss liked my helpdesk experience and didn't mind me learning on the fly, so he offered me a hybrid position where I'd be doing customer service for half the day, and take care of some smaller development tasks for the other half. Eventually, I became more comfortable and competent with the development, and started to take on bigger projects. This was a GREAT experience, as I finally felt like I was getting good at a really marketable skill; however, I still really wanted to make a game.

Choosing an Idea

After working as a developer for about a year, and tossing around a few game ideas with friends and coworkers, I decided it was time to take it seriously. As I mentioned above, I had too many ideas to count, so if I was hoping for any type of production I'd need to just choose one and run with it. There were a few things I was looking for in my first game:
  1. It had to be relatively simple (in concept and execution).
  2. It had to be something different and interesting.
  3. It had to be mobile and cross-platform friendly (this was 2010-2011, when iOS games were going nuts and Android was just starting to take over).
That's it. Pretty simple criterion, really. A lot of my game ideas required elaborate stories, or multiplayer capabilities, or multiple game modes, but all of those had to take a back seat to a simpler idea. That's why I went with No Girls Allowed. I had this Boys vs. Girls idea that would take place on a playground or in a park, and would play sort of like a tower defense, but in real-time, and with a better goal than simply don't die. I sketched out a few characters in the way you do quick sketches nowadays (MS Paint), and while they were really ugly, they still got me going in the right direction. Seriously - they weren't good - take a look at a few of them.


Next, I needed to figure out how to make these look better, and how to make them interactive.

Picking a Game Engine

Believe it or not, choosing a game engine turned out to be by far the biggest headache of this whole process. I'm sure this was mainly due to the fact that I was brand new to this type of undertaking. I had a buddy who had also done some development that wanted to help me make the game, but he didn't have any experience in games either. So, I consulted Mr. Google. I was specifically searching for cross-platform game engines, and at that point, most people were recommending using Flash, so that's what we went with. We discovered that there are dozens of similar Flash game engines, and after some research, we landed on FlashPunk, using the FlashDevelop IDE.
At first, our roles were really well defined. I was the designer and project manager, and he was the developer. For my part, I got to work transforming my crappy MS Paint mock-ups into animated characters using Adobe Flash and a nifty free tool called SWFSheet (to convert .swf files to sprite sheets). I got pretty proficient at it, and at my peak, I was able to knock out about 2-3 new kids per week. My counterpart was doing a good job too, finishing up one or two big tasks per week. After just a few months, we had a solid working proof of concept. We had girls spawning and coming across the level, and the boys going out to meed them when we clicked the button, and the kids were able to fire their weapons from the fort. Things were looking great. However, we had overlooked one big thing. All of our testing was being done on my computer, and we hadn't even looked at it on a mobile phone yet. Once we got it up and running on my Motorola Atrix, we realized that unless we were able to optimize the crap out of it and make it about 4 times faster, there was no way we could release it into any mobile market.
The thing seriously ran slower than molasses. In a game that was supposed to drop you right into the action, it took the enemies a good 2-3 minutes just to make it across the path to the fort. To put it into perspective, now they get to your fort in about 20-30 seconds. This was obviously unacceptable. We spent a couple of weeks trying to improve the performance, but it was all in vain. We knew that we had to scrap the whole thing and look elsewhere.
One thought we had was hey, we're gonna be doing 3d games eventually, so why not choose an engine that supports it?. However, now it was some time in 2012, and the two most popular 3d game engines were the Unreal Engine, which didn't export directly to Android at the time (I think that was the reason, at least - it's been a couple years), and Unity3d, which was hundreds of dollars even for the basic versions of the mobile add-ons. Eventually, we decided it would probably be best to stick with a free 2d engine, and the most attractive one we found was Cocos2dx. Neither of us had done any C++ programming, which is what Cocos2dx uses, so we were fighting an uphill battle. The task fell upon me to hack my way into getting the game going, while my friend wanted to ramp up his C++ skills, taking the time to do some tutorials to get the basics down.
Another month or so went by, and we were hating C++ more and more. It was still Greek to him, and I hadn't gotten any further than recreating our main menu. C++ was so different from the things we had experience in (C# and JavaScript), that it ultimately proved to be a hurdle that neither of us wanted to get over. It got so bad that my partner actually decided he was done working on the game altogether. I didn't blame him at all - it was so frustrating I actually needed to take a little break myself.

Unity3d to the Rescue!

I sat out of the development part for a few months, focusing on cranking out some new characters, figuring I could always go back and find a good engine to use. Now that I was on my own, I knew that I would go crazy if I worried about both design and development at the same time, so zero coding was done during this time. I was able to get my animations probably 90-95% done during this time, and then May 2013 came along. In May, the precious, wonderful saints over at Unity3d decided that they were going to make my life a lot easier by announcing that their basic mobile version would be free for everyone. I didn't think twice before downloading it, and the more I learned about it, the more I loved it. Unity3d allows you to write in either UnityScript (basically their version of JavaScript) or C#, the two programming languages I had experience in. The GUI is also a breeze to learn and a joy to use. I started back up on development, and was able to get the game further along in a month than in the 6 months we stuck with Flash. It was honestly a revelation - I finally knew why everyone was so high on it. Within a few months, I had almost everything done, and was working on things such as data storage and in-app purchases. If you are a game developer or aspiring game developer and take anything away from this blog post, make it this - if you haven't decided on a game engine, choose Unity3d. That's all. K, back to my story - now it was September, which unfortunately meant I had to go back to school for my last semester.
Don't use this as an excuse to skip out on college, but I honestly hated every second and every wasted brain cell that went into finishing that last semester. Whenever I opened a text book, all I could think about was why am I screwing around with this when I could be working on No Girls Allowed? Still, I dug deep, swallowed my pride, and suffered through the next three months, eventually getting my Bachelors Degree in business administration - if you don't believe me, here's the proof!

The Release

Fast-forward about 3 weeks, and No Girls Allowed was ready for beta testing. I've come to find out that Android's built-in beta program is nothing short of friggin' awesome. With the help of a bunch of friends and a few strangers, I was able to squash a bunch of bugs I previously had no idea about, as well as get valuable feedback on things such as the leveling-up system, difficulty, etc. A couple months later, I had a game that I felt was ready for production. I also felt a little pressure (good pressure) when a certain awesome Google+ page (+Google TV Friends) went ahead and shared my beta version with their 96k+ members. That was pretty intense, as I knew that their members wouldn't be able to find it in the Play Store yet. Luckily, as I mentioned earlier, I felt like that version was ready for release, so I felt good about going live and riding that wave of free marketing they just offered me. I went ahead and clicked the "Promote to Production" button and went on to tell everyone I knew about it. Yay, I have a game in the Play Store!

Life after Release

Well, now it's been 12 days since I clicked that button. Unfortunately, I'm not a world-famous indie game developer or millionaire yet (not quite). As of right now, I'm sitting at just 120 downloads, which is far from spectacular. As far as money goes, I've basically made none. I've made a little over $6 in ad revenue and the only people to make an in-app purchase have been coworkers who both wanted to be the first to say they supported me. I'm not worried about it though, because most people that play No Girls Allowed seem to enjoy it (correct me if I'm wrong), so I assume my biggest problem is not knowing how to market it. I've submitted it to a bunch of sites for review, but most of them either haven't gotten back to me, or are asking for a whole bunch of money just to download and play it. I'll probably have to bite the bullet and pay for it, but I haven't narrowed my list down to decide which sites I'd most want to give my money to for a review. As an independent developer, it's not like my pockets are all that deep. If I do figure out this whole marketing thing, I'll definitely be letting people know some tricks right here on this site. For now, I'll just chalk this up to the woes of being a new indie developer.

The Takeaway

So, in an attempt to condense this sucker into a small snippet of advice, I'll leave you all with these pointers - take them for what they're worth:
  1. If you really want to make a game - get started. Don't make excuses.
  2. Start with one of your simpler ideas.
  3. Be original (NO MORE FLAPPY BIRD/BEJEWELED/CANDY CRUSH CLONES!!!).
  4. Use a game engine that fits your experience.
  5. Set small, attainable goals.
  6. Don't get discouraged or overwhelmed. If you do, take a little break.
  7. If I can do it, anybody can.
Thanks for visiting my blog, everyone! I know it was a little long-winded, but hopefully you found something in this post that made it worth your time. If you have any questions about the process, or want me to address anything in particular, let me know in the comments.

Monday, December 30, 2013

First Blog Post Ever - No Girls Allowed Beta


UPDATE:

No Girls Allowed is now out of beta and on the Play Store. Go get it here!


I sure hope I can contain my excitement and not get all willy-nilly with my grammar, but I'm pretty freaking stoked. Not only is this my first blog post ever, but the post also happens to be about the release of my very first video game. I've been working on this thing for too long, and it will feel awesome to finally get it off my plate and onto your eager phones and tablets. So, without further ado, Trick-Bow Productions proudly presents: No Girls Allowed!



I know, right!? Wow! The basic premise is that you control the boys in the war against the evil little girls, and have to take out their base before they destroy yours. You can unlock 9 different boys to aide you on your mission, along with 6 different weapons to throw or shoot. Once you unlock your units and weapons, you'll be able brag about it on Facebook to show your friends how amazing your army is getting. Seriously, who wouldn't want to know that you've been spending your time chucking dirty diapers at little girls?

Platforms

I'll be releasing this sucker on Android first, and hopefully most other major platforms within a few months. I've tested it on Android, iOS, Windows (desktop), Mac, and BlackBerry so far, and it seems to chug along just fine on all of them. Unity3d made that part of my job incredibly simple, and I'd highly recommend this game engine to anyone who is thinking about getting into a little indie development.

Not-Quite-Done Stuff

Now as awesome as this looks, it's still not quite fully-baked. After all, it is just a beta release. For instance, the game isn't hooked up to the social networks just yet. There will also be in-app purchases for extra game currency and a few special items, but these aren't active yet either. Finally, I haven't implemented a high-score system into it yet. I'm planning on working these out during the beta period (over the next month or so), so be patient with me!

Go Forth and Download!

Like I mentioned earlier - I'm releasing it on Android first, so that's where all the fun testing will take place. To be a part the beta test, you'll first need to join this Google+ Community I set up for testers. Once you've joined, you'll see a link that goes here, which is where you can opt in to become a full-fledged, bonafide beta tester. I'll keep you all informed when I have it ready for the other platforms.
Thanks for taking the time to check out my post - I really hope you enjoy the game! Keep in mind that this is a one man show (seriously - from website development to artwork to composing in-game music, etc.), so be nice, but honest in your feedback. Also, I'm definitely open to ideas and suggestions, so don't hesitate to share your thoughts and ideas with me either in the comments here or in the Play Store. I look forward to hearing from everyone!