Sunday, 30 December 2012 4 comments

Unity, Futile & C# - Part 2

If you read the first part of this series you will know I am transitioning from Corona SDK to Unity. More specifically Unity and the 2D rendering framework, Futile. The purpose of this blog post is to further diarise the process as well as providing some level of documentation to Futile which is still in its infancy.

Day 8
This was very much a day of highs and lows. To match to the iOS version of Astavoid I wanted to replicate the screen transitions. However, within Futile at the moment there are no transitional effects between FContainers so they snap rather unattractively. Thankfully, and purely by chance, my screen transitions were straightforward and just gave the effect with text animations. As this has already been expressed in previous entries, this was achieved with the excellent GoKit by prime[31]. Definitely have a play around with this and to help you its featured heavily within the Banana Demo project.

With this in the bag I thought I would experiment with getting GameCenter integrated into the game as the one on the Appstore features OpenFeint which is now deprecated. I started off thinking this was going to be a straightforward exercise but got a little confused with how the GameCenterPlatform class worked with Unity, scripting and Futile.

This is where my day started to go a little downhill and this was typical of not knowing enough about how Unity worked. My first mistake having implemented the code was wondering why ads weren't appearing within the Game window of the Unity editor.

What I hadn't done was to enable GameCenter under iTunes Connect for a unique app. Only with this will ads works. To enable follow these steps:

  • Log on to iTunes Connect
  • Click on Manage Applications
  • Ensure you have an app which is in an edit state such as waiting upload or an equivalent to modify GameCenter state.
  • Click on Manage Game Center
  • Click "Enable for Single Game."
  • Click Disabled.

The Disabled button toggles between Disabled and Enabled. To disable your app for Game Center testing, click Enabled. Once you disable, you will no longer see your app in the Game Center sandbox. You are only permitted to disable up until a version of your app goes live with Game Center. Enabling Game Center for testing unlocks the Game Center interface to allow you to set up your leaderboards and achievements.

Once I had set this up I created one Leaderboard and one achievement to ensure there was content.

Alas, still no test advert coming through. It was at this point I thought that maybe they didn't come through within the editor and I need to test on my device. This was my second mistake of the day.

For some reason I didn't realise it was packaged into an Xcode project. Having come from Corona SDK this step didn't happen it just got compiled and you dragged the compiled .app file onto the iTunes to add to your device. This was when I realised I hadn't setup the bundle identifier properly either.

The next mistake I made was trying to compile the xcode project to the Xcode simulator. The reason I was trying this was that I wanted to ensure the project worked before trying to put it to my device. I was getting some fundamentals errors on compilation, over 200 in fact, which I felt just couldn't be right. After some twitter conversations and scouring the internet I found you can only compile to the device.

So after some wasted hours I now had my app on my device, but still no adverts. It was time to call it a day.

Day 9
A new day brought a clearer head and renewed vigor. When I first started out with game development I wanted to write my own code and therefore learn and understand the most. But having done it now for a year and having to balance my time with a full time job and two young children, I've concluded that using third party plugins is ok. Yes there is a cost to them sometimes but I weigh that up to cost I put on my spare time. Yes I may never make it back on my games in the near future but for the sake of $20 there is no point me struggling for a week trying to get something to work.

This clarity was reached to some degree during my investigations on Day 8 when I repeatedly came across postings and recommendations for prime[31]'s GameCenter and Ad plugins. Having already experienced the ease with which their GoKit was implemented I decided to take the plunge and bought the GameCenter and AdWhirl plugins.

The plugins are excellent and can be setup with a few very easy steps.

For AdWhirl first setup an account and get your Publisher ID as this is what the prime[31] plugin requires. In regards to ad providers I chose a distribution of iAd (70%) and AdMob (30%).

Assuming you have followed Matt's banana project to a point you would imported a futile package, dragged to the Unity hierarchy and assigned a script to your Futile game object. With this assumed open your script and declare a private variable such as private string publisherId = "your id goes here"; . Then within Start method, and this apparently is the important bit, make AdWhirlBinding.init( publisherId ); your first call.

Having implemented this I built for my device and tested and BINGO! adverts start coming through.

Again, buoyed on by this working I turned my attention to GameCenter. I had assumed I had setup everything up in the iTunes Connect steps explained above so I set about implementing it.

Like all implementation's of GameCenter you must first check that GameCenter is available and then you authenticate. For the purposes for testing I am resetting the achievements each time to ensure the banners etc come in. The code, again in my Start method is:

// Do gamecenter stuff ... Is GC available?
if(GameCenterBinding.isGameCenterAvailable())
{
	// Yep looks like it is so authenticate the player;
	GameCenterBinding.resetAchievements();
	GameCenterBinding.authenticateLocalPlayer();
	GameCenterBinding.retrieveAchievementMetadata();
	GameCenterBinding.showCompletionBannerForAchievements();
}

Before testing on your device ensure you log out of GameCenter as when testing on your new game and you log in it will go into Sandbox mode while in development.

Success!!

Day 10
A very successful day on day 9 so to continue on with this I thought I would hook up the achievements when a certain distance was achieved. All I do is create a method within the Update method of my game scene to check whether a certain diatance has been achieved:

void checkAchievement(int _score)
{
	if(Main.instance.BestScore == 0)
	{
                // First play
		Main.instance.BestScore = _score;
		GameCenterBinding.reportAchievement( "AA001", 100.0f );
	}
	if(_score >= 5000 && _b5000 == false)
	{
                // Distance achieved
		GameCenterBinding.reportAchievement( "AA002", 100.0f );
		_b5000 = true;
	}
	if(_score >= 10000 && _b10000 == false)
	{
		GameCenterBinding.reportAchievement( "AA003", 100.0f );
		_b10000 = true;
	}
	if(_score >= 15000 && _b15000 == false)
	{
		GameCenterBinding.reportAchievement( "AA004", 100.0f );
		_b15000 = true;
	}
}

If a score has been reached then via the GameCenterBinding i.e. our prime[31] plugin, it sends a message to iTunes connect to see if an achievement has been completed. This is the case because we provide the id of the achievement and the percentage complete. As I specified GameCenterBinding.showCompletionBannerForAchievements(); in my initialisation method the player will get instant satisfaction as the achievement banner will be shown. This all happens on a separate thread so no effect on the game's performance.

The next challenge was to take on the music and sound effects within my game. I slightly misunderstood how this worked and didn't take advantage of Futile's sound manager, FSoundManager. So what I chose to do with this was to adapt the Banana project implementation and create a separate sound player class:

public class SoundPlayer
{
	static public void PlayBlipSound()
	{
		FSoundManager.PlaySound("Blup", 0.95f);
	}

	static public void PlayMusicSound()
	{
		FSoundManager.PlayMusic("music", 0.3f);
	}
}

This implements the in-game music and the button sound effect. The gotcha I had here for a little bit was I didn't notice the difference between the methods of PlaySound and PlayMusic. All I now need to do is within my Start method of my main class is to call SoundPlayer.PlayMusicSound(); and viola music a go-go. Similarly, in my SignalRelease (eventhandler) methods for my buttons I call SoundPlayer.PlayBlipSound(); to have a sound effect when my buttons are touched.

Day 11
Jumping around a little bit I refined the resolution logic:

FutileParams fparams = new FutileParams(true, true, false, false);
fparams.AddResolutionLevel(480.0f, 1.0f, 1.0f, "");
fparams.AddResolutionLevel(960.0f, 2.0f, 2.0f, "-hd");
fparams.AddResolutionLevel(1024.0f, 2.0f, 2.0f, "-hd");
fparams.AddResolutionLevel(1280.0f,	2.0f,	2.0f,	"-hd"); //Nexus 7

and worked on my Rocket retina graphics. Again, going back to old faithful in Texturepacker and recreating atlases with the appropriate suffixes.

I also worked on touch logic whereby a user clicking on the screen would allow the rocket to change "depths" giving the illusion of going in and out of the asteroids and in turn running the sprite animation of the rocket.

Day 12
I am unconvinced about whether the accelerometer is the right way forward for this rewrite. However, I want to make sure I don't over engineer this game as that was the original control system and move on to pastures new and new learnings. What I did decide to do is implement a Dpad and evade button just to see how it works.


I wanted to keep the style minimalist and non-intrusive as possible. How I implemented was to create shapes. One of the complete Dpad and then a further 4 for each direction which is then created as a separate FButton and placed over the top of the complete image. The evade button will be used to run the rocket sprite animation and change the alpha of the asteroids so the player knows which asteroids to avoid. Also a little rearranging on the screen to ensure it doesn't become too crowded. Tested on various resolutions to ensure all sits correctly.

Day 13
Back to graphics and animation today and that is to create a rocket flame / exhaust. I had a slight headache over how to implement this. In the current version using Corona this is a particle system using a third party plugin called Particle Candy which was very easy to use. However, the new Unity particle system Shuriken was something that my novice experience was struggling with and not one I could see how it could be directly implemented using Futile.

Instead I chose to animate via Flash and export the frames from Flash into my atlases and create an object to play and scale the exhaust appropriately. The effect I am pleased with but feel I will need to tackle the particle system sooner rather than later.

Day 14
Big subjects were tackled today, collision detection and multi-touch. Let's start with the latter.

Multi-touch is important for my game as I want to move and evade at the same time and the normal signal release (eventhandler) won't even queue messages as its first come first served.

I'll confess I made a major oversight with implementing this and wasted a lot of time. An important point is to ensure you also inherit your class from FMultiTouchableInterface and then to update your Stage Handlers to include and remove multitouchtargets.

Code:
override public void HandleAddedToStage()
{
	Futile.instance.SignalUpdate += HandleUpdate;
	Futile.touchManager.AddMultiTouchTarget(this);
	base.HandleAddedToStage();	
}

override public void HandleRemovedFromStage()
{
	Futile.instance.SignalUpdate -= HandleUpdate;
	Futile.touchManager.RemoveMultiTouchTarget(this);
	base.HandleRemovedFromStage();	
}

with the final thing being is to implement what should happen when multiple touches occur with the public void HandleMultiTouch(FTouch[] touches) method. This should now allow your game to detect and react to multiple touches.

The next thing to tackle was collision detection. I managed to setup a collision detection of sorts by again having a method within the Update method checking whether one FSprite's position overlapped with another FSprite's i.e. rocket and asteroids, While it worked I found it wasn't responsive enough.

Day 15
Having thought about this some more I was coming to a realisation that maybe I needed to dig a little further into the Physics system. While there isn't one setup specifically within Futile the community has written FPhysics which allowed more realistic collisions to happen between objects. This in itself through up some interesting points of research. The main problem still was that neither Futile nor FPhysics implement fully a method to programmatically initialise rigidbody and in turn a collider in order to take advantage of collision detection inbuilt to the Unity Physic system. Where it should be possible to create something like the following:

void OnCollisionEnter(Collision collision) {
    foreach (ContactPoint contact in collision.contacts) {
        Debug.DrawRay(contact.point, contact.normal, Color.white);
    }
    if (collision.relativeVelocity.magnitude > 2)
        audio.Play();
    
}
this will not fire in either of the two earlier instances. On discussion with Matt what it has highlighted is that it is very possible but in my novice state my understanding of Unity's components means that I am going round in circles.

So that brings me on to what to expect from part 3 of this series. The focus will be on bridging the gap between Futile and 2D in Unity to tackle the particle system (Shuriken) and the physic system to implement an equivalent experience to my Corona SDK game.

It should be noted for those that use Corona that this seems like a huge amount of work when Corona wraps this all up for you and that is indeed true and one of its big advantages. However, I have seen enough of the potential of Unity and getting familiar with its setup to know the short term pain will be more than worth it.

Until next time, Happy New Year!

Sunday, 23 December 2012 3 comments

Spriter: helping your 2D animation woes

I'm no artist, in fact barely a coder but one thing I struggle with is decent 2D art / animation. I can't remember why or the date but I have used Flash on and off for doing my art and animation for over 10 years but have struggled to find a decent alternative. I think what I like about Flash is the nuances of the tool for drawing that I am yet to find else where.

Its for these reasons that I started an investigation into something that could replace or complement my current toolset.

If you look at my current game on the market, Astavoid, I have a distinct style. This more than anything is minimalist given the time I have to focus on the art. I was told, and I forget the source, that its important as an Indie to do your own art as you aren't reliant on someone else to do your work, minimises cost and therefore a master of your own destiny. With that of course comes budget. I for some reason, again forgetting why think its age, have a copy of Flash CS3 which is by no means a feature rich product by today's standards. However, it is something I am reasonably comfortable with.

My route of investigation took me to Spriter. Spriter if you don't know is an animation tool for 2D games. Larger, more smoothly animated characters, all running for your favourite engine and platform. It had a very successful kickstarter in April 2012, of which at the time of writing the product sits in Alpha.

It is for the purpose of this blog to see whether Spriter can compliment an art package to provide quicker animation techniques over maybe that of tweening in Flash.

So lets begin, to start this off I will create a little gun man type thing which is a concept I have been working on. To help you visualise my minds eye we jump ahead a little to the final image.

Having read the web pages of Spriter it looked like my animation needed to have component parts. This is because Spriter accelerates the animation process by transforms or skeleton rigging to provide pivots and movement where required.

My first step was to breakout my character into various body parts. As you see from the image above I have a character with a gun. What I will look to animate is the character shooting with a slight bit of kickback / recoil.

For that reason I split my character out into sections:
  • Head
  • RightHand
  • RightArm
  • Gun
  • Body
  • Feet
  • LeftArm

These are organised as such and this order to give the relevant layer depth to give the illusion of the character holding the gun etc.

With this now in situ I save out the layers one by one as PNGs hiding all but the layer I'm saving to have distinct images.

Next is to fire up Spriter, if you haven't done so already download here and then once installed create a project and then import all the images we have just saved out. We then in turn position the images on the worker area to reconstruct our character. All going well it turns out like the one below.

The next thing to do is create keyframes along a timeframe, identical to how implemented in Flash, to denote when something should happen. This is the point whereby you start your experimentation. For mine I will add a keyframe around frame 80 (assuming a 60fps game) to move the gun to an aiming position. To do this we simply click the object "gun" in either the "objects in frame" window, or on the working area and a transform box will appear

To make it do something you can either move it (replicating a tween within Flash where it will animate to), scale or pivot. For the purposes of what I am doing I will pivot on the bottom left corner so the top right is pointing up. It's as easy as that!

The process now becomes trial and error rather than complicated keyframe drawing only to find there is an error.

Once you have completed your keyframes are ready to export out ready to put into a spritesheet / atlas. Here is something you must watch out for. In the current version of Spriter, at time of writing the alpha version, only the keyframes will get exported and not every frame. This of course for an animation is next to useless.

However, not all is lost. Dependent on the length of your animation this workaround could be pretty tedious but what you need to do is add a keyframe to each frame of your animation. Then when go to File -> Export to PNG all frames will be exported for you. Now you are ready to put your keyframe animated images into atlases / spritesheets with a tool like Texturepacker for use within your game.

And there you have it an animation in next to no time. So what are my feelings of Spriter. To be honest huge potential as the process of pivot and move was very easy with the key being to split out my character to component parts and the rest is a doddle. I will certainly be intrigued to see how the beta and full release of the product turn out.

6 comments

From Corona & Lua to Unity & C# - Part 1

For those of you who have followed my blog for a while you will see that title and think: "Changed his mind again!!", and you'll be right. I was taking my last blog a little further and experimenting with Cocos2D and Kobold2D. Both proved excellent and Steffen Itterheim's book Learning Cocos2D gave me a good grounding in both.

I think the thing that I started to get disheartened by was as soon as I finished the book Steffen announced he would be transitioning from Kobold2D to KoboldTouch. While that is no great shakes in that I hadn't really started I thought to myself given that I was looking to transition did I want to go with something that was closer to my core, .Net. The rationale behind this is that although I have released apps in Lua and Objective-C they took longer than I wanted as I got used to the syntax and idiosyncrasies of each.

Like a lot of people I am a follower of Matt Rix (@mattrix of Trainyard fame) who had spoken of a 2D code centric rendering framework he had been working on called Futile for Unity. I was intrigued by this as I had wanted to dabble with Unity for some time but had been put off by the plethora of buttons and options as well as a third axis I hadn't even contemplated :).

To start off with I watched the videos on Matt's website http://struct.ca/futile which gave me a decent insight into what it was capable of. I'll be honest I had to watch them each about three times to break through my mental block of Unity but what was becoming clear is that Unity only forms about 20% of this approach. MonoDevelop would become my friend and that was the point, code centric. So I thought I would take the plunge. First off I followed the steps on Matt's Github page:

How to open the project

  • Grab the project from github and put it somewhere - For the lazy, here's a zip of the whole repo
  • Make sure you have Unity installed
  • Go into BananaDemoProject/Assets/Scenes and open FutileDemoScene.unity
How to make sure you're running it at the right resolution
  • Go to File -> Build Settings -> Click "PC and Mac Standalone" -> Click "Switch Platform" (if it's already greyed out, you're good)
  • On the Build Settings page, choose Player Settings
  • Under Resolution and Presentation, set the size to 960x640 (or 480x320, or 1024x768)
  • Go to the "Game" tab
  • In the top left dropdown, choose your resolution (instead of "Free aspect")
  • In the top right, make sure "Maximize on Play" is enabled.

Having followed these steps and watched the video while playing around with the code I personally started feeling quite comfortable with the concepts. In particular the third video of just over an hour really helped cement my understanding

For the purposes of clarity I am using Unity 3.5 (not 4.0) and took advantage of Unity's April 2012 give away on iOS basic. The latter is obviously required for publication and distribution but the free one to PC and Mac can still be designed to and just change the player settings to 480 x 320 for example.

Like most things when you start with something new I need a focus to adapt to my own requirements. This is the only way I find I can learn is to play around with things and try and try again. What I thought I would do is document my day to day transition from Corona and Lua to Unity and C# which the latter seems a popular option. For me the code for Astavoid was actually very similar to Matt's BananaDemoProject so unless I make paricular reference to code I would strongly recommend having a nose around there.

What should also be noted is I'm a hobbyist Indie (not sure that even exists!!) but means I can only afford at best 4 hours a day in the week and perhaps a little more at weekends. So my definition of a day is actually quite short so your progress could be even quicker.

I thought writing a new game would probably be too challenging so instead I focused on porting Astavoid from Corona SDK and Lua to Futile/Unity and C#.

For those of you who haven't had the pleasure of playing my first game its a very straightforward space evasion game that is available free on the App store. Why not download it for reference, its free after all :).

Day 1
First and foremost I didn't want the same hassle I had when I first wrote Astavoid concerning fonts. On the iOS and Android devices handle paths differently so I followed the lead of Matt's video tutorial and purchased Glyphdesigner. Really not sure why I didn't do this the first time but is an excellent tool to ensure compatibility of fonts across devices. Furthermore, I could include this font image within my textures / atlases. The font mapping file (.txt) also needs to be included within your resource folder in Unity.

The next tool to your arsenal is the excellent Texturepacker this proved to be a lifesaver when I first wrote the game with Corona and is equally as effective for Unity. The only difference being that it outputs a text file rather than a Lua file but the transition is seamless. I couldn't recommend the product enough and, again, if you watch the video's on Matt's page this is what he is using.

So with my font and background graphic within my texture I was now in a position to create my first scene. Nothing too strenuous as really I was dealing with 5 text objects and a background image. Needless to say this was very straightforward. I created my Main.cs (C# script) which I dragged onto my Futile object. Then I open MonoDevelop and put the appropriate logic into the Start method of the Main class. Ensuring of course to add the labels and sprites as children of the scene (AddChild(object) so that they show up. Missed this one a few times :)

The result was a fair reflection of the original title page, other than the fact it didn't do anything at this stage:

Day 2
Buoyed on by my first day's achievements, and when I say day I only mean about 2 hours, I set about bringing the asteroids into my texture and look to provide some movement.

I started to organise my code a little and create an FContainer (or scene) to split up the various screens I was going to need. So I created a TitlePage and a GamePage.

Within my Start method on the Main class I did a call to the title page which in turn did a call to my game page. To conclude the navigation my game page, via the pause button, would return me to the title page. This simple transition meant two classes representing the scene, and my Main class with its singleton instance controlling which one to display. At this point I was calling the scene methods directly and not by button touch.

With this now working well I revisited Texturepacker and dug out my asteroid artwork and added it to my texture. I then re-published and added my new texture to the Unity project.

There is no specific physics engine built into Futile specifically aimed at 2D at the time of writing. Unity of course contains the powerful NVIDIA® PhysX engine but the whole purpose of using Futile was to make my life easier. So on day 2 of my adventure I focused specifically on animation

Thankfully Matt has considered animation / tweening and incorporated Prime31's GoKit library into Futile which makes animating the Futile objects very easy. All I had to do is create a base class for my asteroid object and derive from this for my different asteroid types to give the perception of depth. I then used the GoKit library to tween these asteroid objects relative to their size and depth and then cull when off screen.

Day 3
The aim of day 3 was to hook up the title buttons via touch. Again this is straightforward enough through Futile's touch manager. By reviewing the code of the Banana demo project it is straight forward to see how the touch events via a signal release and then the relevant method to call. From these methods I was then calling my instance to call the scenes on the stack. This makes traversing the scenes easy.

An additional update was to apply the distance counter to the update method of my scene. My game by this point is running at a very smooth 60fps which exceeds the 30fps I was running at with Corona. Not a limitation of Corona I should say but mine in writing efficient objects and caching correctly. I remember probably spending about 2 months on this subject alone optimising my lua code and get it done in a day with Futile / Unity! I use a modulus to only update the counter every other second (or update) to keep the distance score a little more realistic.

Day 4
With the principles of the scene setup I turned my focus to the rocket sprite. Its worth noting at this point that I am using existing assets that may need to be modified dependent on what control mechanism I go for.

With this in mind I created another texture atlas in texturepacker for my rocket and therefore not over bloating my other atlas. This is in part because I made the decision to add in my space background to the original atlas as it would be used on multiple scenes.

I also revisited my asteroid code and inherited more from my base class to streamline my code and adhere to the DRY approach of Don't Repeat Yourself. With this refactoring done I created a fourth size of asteroid to run in the background as a form of parallax asteroid belt.

Day 5
This was a big update day! The first was tackling how to handle storing of data within Unity. I learnt that this was done with key value pairs that could have certain types attributed to them such as strings, floats, etc. I looked at using the PlayerPrefs class to store information for my best score but thought this needed to be extended a little to create my local leaderboard. I found something that I could base my class on here and adapted appropriately. Having returned all scores to my list they are sorted and then limited for my purposes

As well as adding in my best score logic and leaderboard I ensured that all buttons triggered events. This meant converting the FLabel to an FButton and in my case adding a transparent image behind the text for the hit state.

Day 6
To mimic the Astavoid app that is already in existence I applied the GoKit tween logic to my Flabels and FButtons for the transitions between pages / scenes. The transition effect is done within the constructor of the scenes FContainer class while I wrote a specific TransitionOut() method to handle the text and image objects movements back to the start. This works really well with smooth movement and some nice effects such as easing in and bouncing.

Day 7
Android was definitely an area that took a lot of development time up with the original release of Astavoid. The fragmented screen resolutions took some thinking and some adjustment in the code. While iOS isn't there yet its certainly heading in that direction which is why I was relieved to see that Matt had given it some consideration within Futile.

To tackle this I revisited by trusty tools of Texturepacker and Glyphdesigner and increase the size to be scaled appropriately for retina screens. I looked into Matt's Banana project to get a feel for the text sizes he used for this project and played around with my ratios as I had three different text sizes to his one. From this I setup the AutoSD feature of Texturepacker which works to the principle of largest size and then scales down the different ratios as are relevant.

Obviously we would work to the Retina x2 (or even x4) normally but I haven't had a chance to go back to the drawing board on the graphics so just want to work out the logic for the resolution switching.Highly recommend if you are starting out you work to the largest resolution. There are lots of guides out there but this one is pretty useful.

The result being that I have simple parameters set as part of the Futile init that determines the width that is relevant to that resolution, the scale factor and the suffix of the atlas file to pull in. For debugging purposes the scale ratio and the file being used is echoed to the Unity console so you can make sure you are scaling correctly.

A pretty productive first week I think you agree. I have learnt loads in this time and while have lots to learn I feel confident of getting this simple game ported.

Thing to note is that Futile is in its infancy at the moment so documentation is pretty light. However I found Matt Rix (@Mattrix) and Whitaker Trebella (@wtrebella) of Polymer fame, to be incredibly helpful with my annoying question. I can also help with the basics and can be found at MyGamingProject @gameproject10k where I will be happy to help. Part 2 can be found here covering Collision Detection, Multi-touch and sound will be tackled. Another busy week :)

 
;