UE4 – Blender – Makehuman workflow cheat sheet

Good evening! Tonight’s entry is my attempt to document a few things I have picked up this past weekend as I start to develop my next project. I decided to make some animations using blender. I have mostly created static meshes in blender, but I decided to try to make my own character animations. Here are some of the things I have found.

 

Workflow from makehuman to UE4

I used makehuman to create a pretty decent looking character. I created some custom cloths for the character and exported the model with rigging (basic game rigging in makehuman) to Collada format. I tried using the special blender-makehuman format, but I had issues when the skeleton was imported to blender.

I imported the model into blender. I read that UV unwrap is necessary for textures to appear in Ue4, but I didn’t have to perform this step. I simply went into UV editing mode and selected the textures and made sure they were scaled and position correctly on the faces.

I am not going into any detail about how to animate, I found it to be pretty intuitive. Change to animation mode, pose the character and then hit I to insert keyframe.

When you are ready to export to FBX for UE4, set the Unit Scale under Scene to 100 units metric (or whatever you want. It will equate to the same number of ue4 units) Make sure that whatever unit scale is set matches on the FBX export dialog.

 

Other stuff I always have to lookup :)

Fly Mode - Click the camera icon under the scene and then Shift + F to enter fly mode. ASWD to move, left click to return mouse control, right click to return the camera to the previous location.

Keying animation frames – To insert a keyframe in animation mode, make sure pose is selected and hit I (Insert Keyframe) and then ‘Whole Character’

deleting animation frames – This only works on the dope sheet. Make sure to right click to deselect all, then hit B to rectangle select any frames to delete. Hit X to delete selected keyframes

To rotate meshes, select the mesh and hit R and then whatever axis (X Y or Z)

 

 

 

 

 

Stop the XOID! XBLIG postmortum.

Good day! I have been procrastinating way too long since my last post so I would like to break today’s update into two main sections.

  1. Stop the XOID! XBLIG postmortum, plus an update on what’s next.
  2. A general discussion about XBLIG development and also gamedev in general.

 

Stop the XOID! was every bit as challenging as I thought it would be. Developing a game from a child’s inspiration was fun but incredibly time consuming. The game took way too long to make for the little content that is in the BETA release and required a large amount of rework to satisfy the creative ideas of the youngling. The game currently has no real sense of progression or purpose which is something I would like to change for the PC release. The box art is dark and hard to make out, and perhaps the screen shots are not as well done as they could be. So whats next? I plan on releasing the full version of Stop the XOID! for PC and possibly also the OUYA console.

As far as development, I would like to start converting the game to monogame and adding PvP maps and a single player and coop story line mode. The way items and upgrades are selected should be radically different and there should be a wider variety of items and abilities. The maps could use a face lift and I would like to add a few different enemy characters. As far as a time table, I have no idea. All of this is up in the air.. Which brings me to my second topic.

I have been developing XBLIG games in off hours for many years with the idea that one day I might be able to take some time and work full time on a project. I have developed several titles that are rather limited in scope but are fairly entertaining non the less. I have recently decided that I should take game development more seriously and establish a 3 year plan that will enable me to make dreamwagon viable as a company and allow me to take on the serious projects I have had on the back burner for years. I decided to make Stop the XOID! because I thought it would be a nice thing to do and give me a break between two XBLIG Avatar games I had in the pipeline. I had no idea what to expect as far as interest in Stop the XOID!, but I was developing purely on the zeal and excitement that J had for the concept.

Although I was not expecting big numbers, I did think there would be some interest in Stop the XOID! so when development started to go much longer than anticipated, I did not really worry about the lost time that I could have been spending on other ideas. I have to admit I was shocked by just how low the numbers were for Stop the XOID!

Some download numbers to put it all in perspective (Not sales):

Stop the XOID!:   Released April 28th. (54 days on market)    Total downloads:    334

Avatarzilla:             Released May 28th.   (24 days on market)    Total downloads: 9727 

 

Now I understand that Stop the XOID! was released with a couple of things that could be improved, but what can be measured here is interest in the game. People viewed the box art and screen shots and chose not to even download it. As a game developer with the aforementioned ’3 year plan’ when I sit down to assess the route to independent, and more importantly, self sufficient game development, which way should I chose? Deciding what to take on next is always a bit of a struggle for me and the temptation to make a successful ‘catchy’ game in order to create a budget for a real title is always there. I have not yet created my magnum opus, in fact, I have not even started working on it, and this is a major issue with indie development across the board.

The market has become incredibly saturated. There are fewer of us willing to take a risk on a big idea and instead are content to make a quick and dirty demo to get attention. We make an ‘easy to make’ game instead of tackling the monster idea that keeps us up at night.

All  in all the journey to releasing the XBLIG BETA of Stop the Xoid! was enjoyable and I think with improved content, gameplay mechanics and game modes Stop the Xoid! for PC will be great!

 

 

Stop the XOID! – Step 5: Acceptance

Top of the morning to ya! After much thought, deliberation and bargaining, we have decided to drop the word DROID from the title of our current project and agreed on a new title: “Stop the XOID!”

To catch up on all the back-story of how this game came to life see here. Basically, I decided to create  a game from an idea that my 5yr old (J) came up with. I knew that the path forward would be fraught with peril and that putting a kid in charge of designing a game concept would be very challenging. One of the main concepts I have been trying to explain to him is originality, and with that, we have had one looming issue.

For a couple of months I would listen to J lay out the idea for this game. You fight off little alien robot creatures in a series of underground bunkers and try to defend your base. Along with his description of the game was the pitch for the title “Stop the Droid!” When I first heard the title, I liked it immediately, and thought it would work. I had no idea about the Lucas Arts Trademarks on DROID and the many variants thereof. I had heard about the mark DROID alone being licensed by Verizon, but I really didn’t know all the details of how it happened and was astonished to find out that usage of the word could be problematic for us. Here is a reddit post about it.

It is totally amazing to me that the first usage of the word DROID was in the original Star Wars movie from 1977. The word Droid is ubiquitous in popular culture. Could it really not have existed in writing in or film prior to 1977!? After about a months worth of research I have been unable to disprove by finding any other usage of the word prior to 1977. The purpose of a trademark is to protect a brand from being used in a way that might cause confusion among consumers. DROID is apparently an original and novel creation by Lucas Arts and for this reason we have decided to abandon all references to the word in the title and in the game.

We have decided to use ‘XOID’ as the name of the antagonist alien species.

XOID (pronounced zoid): A bio-mechanical race of robot-like creatures who scour the galaxy for planets to strip-mine for resources.

 

Stop the Droid! Dev update #2

Just a quick update today to show some of the progress that has been made over the last few weeks. I took about two weeks off due to other commitments and well, just needing a break from the project. Many of the items from the first dev update have been finished or resolved.

The armory is now fully implemented with a good array of weapons and units and I have started to work out balancing.  Artificial intelligence is now much improved, but still needs work.  J won the battle over sticky grenades. This weapon did not seem to offer as much benefit as some of the other ideas that were kicked around, but in the end, the little dude wanted sticky grenades.. he gets sticky grenades.

Scope is a moving target

As you can imagine, taking full direct from my son is incredibly challenging and rewarding at the same time. He seems to have a new level idea every day, and each one shares no similarity with the last. I have been trying to keep a running list of the best ideas and we have agreed that we will release five levels for the XBox Live Indie games version of the game. This at least allows me to plan for the first release (To XBLIG) by knowing just about how much time it will take to create each level.

Balance Balance Balance

Yeah, this one if obvious. Balancing even a small set of units in an RTS style game is difficult to get right. This will be an ongoing area of work.

Short teaser of the current state of Stop the Droid!

Sharky Fish postmortem and development recap

On Monday evening February 10th with the the loss of a certain ‘Flappy’ game still fresh in everyone’s mind, I saw several tweets swirling about how little time it would take to make or how few lines of code are in such games. (Random question. What is the genre officially? I default to ‘copter’ game since that is the earliest game I can remember)

I decided that I would spend one night on a random concept to see if was as easy to make as I perceived it to be. (Even the simplest of concepts inevitably take more time than expected).

Why make Sharky Fish?

I wanted to release something small and free to the Play Store to see how the process works. The concept of a little fish dodging sharks and the border of the screen seemed straight forward to program and I knew that the art would not take long to draw and to animate. I am currently splitting time between two larger projects that will take many more months to complete and I wanted to see something be completed and I needed to switch gears for a couple days to refresh. Perfect timing for a random solo game jam!

 

Development Tools

As I mentioned, I have been working with LibGDX for a few months now and have a solid understanding of the framework. I created a new project and started implementing a basic UI. I had some code that I wrote to render buttons and textures at different resolutions, but most of the game was written from scratch. I brought the UI code into the project and designed the buttons and banners in photoshop in about one hour. For the next hour I created the shark and fish images and brought them into Spine. (Spine is a 2d skeletal animation program that is totally amazing).

Instead of creating sprite sheets, I thought it would be easier to create animations with spine. One awesome feature in spine is the ability to assign arbitrary polygons to your animation and then import into your game. Here are the bounds I assigned to the animations in the game.

spine1 spine2

 

I used the LibGDX spine runtime to import the animations and perform collision detection. I used the LibGDX Intersector helper class. The only trick here was to use the computeWorldVertices method on the BoundingBoxAttachment read in from the skeleton. This sets the vertices to world space in relation to a bone and x, y coordinate. Then the Intersector can be used to detect if one Polygon overlaps another with the overlapConvexPolygons method. That was really all I had to do for collision!

Things that saved me time:

  • Used LibGDX Stage to handle different display resolutions
  • Used existing UI framework for buttons and input
  • Used spine to animate instead of making sprite sheets

 

The Break Down

So I went about 2 hours beyond my original 8 hour estimate. Here is how I spent the time.

Development Hours: 5

Art and animation: 3

Testing/QA: 2

Sound: 0

Lines of Code: ~1500

 

 Can I play it?

Sharky Fish can be found on the play store here

Edited – 2/16/2014

I decided to remove Sharky Fish from the Play Store because I think it makes more sense to post as a web game. I used Libgdx and GWT to render an HTML5 version of the game.

Check it out here:  http://www.dreamwagon.com/sharkyfish

I would be happy to share the entire source for this game upon request. (tweet me @dreamwagon)

Daddy, I have an idea for a video game. Its called Stop the Droid!

Actually, the exchange between me and my 5yr old son (Ill call him J) went something like this.

J: “Daddy, I have an idea for a video game. Its called Stop the Droid! Do you like that name?”

Me: “Shouldn’t it be Stop the Droids?”

J: “NO! Stop the Droid! Stop the Droid!”

Me: “Ok, so what is this game all about?”

J: “Droids are attacking you, and you have to fight them!.. and when they get hit, they make explosions! And when you get hit you make this sound. ‘ugggharg!!’ Is that funny? Do you like this game?”

Me: “Sounds pretty cool to me!”

And it was at this point that I realized I was completely tangled in his web, and that I would be spending the next few months working on this game. To be fair, I had been looking for any reason to make another game for XBLIG, and as it turns out, J’s first demand was that it be released to the XBox 360. (He said XBox to be fair, Ill just assume he does not know about XBox One ;)
I was also looking for any excuse to use Spine and the XNA/C# runtime. Spine is an amazing 2d skeletal animation program with tons of supported runtimes.  (Checkout Spine Here)

 

A lesson about originiality

So the next thing I had to do was to find out what this “Stop the Droid!” game was all about. The central idea for Stop the Droid! is a battle against wave after wave of droids from a droid army that is invading your planet. As it turned out, many of the first ideas that were presented to me were very VERY similar to concepts and characters from a certain wildly popular movie franchise that J totally adores. May the force be with you while you try to guess it. We had to have another talk.

Me: “I will make Stop the Droid!, but we cannot use Anakin, and we may not use Obi Wan. They are not our own ideas. We have to be original. Do you know what I mean?”

J: Blank stare

Me: “You need to think of exactly what will happen in this game, but most importantly, we must come up with our own characters and game-play.”

And that is when it started to get really fun.

 

Taking direction from a 5yr old.

I decided that my part in this wacky journey would be to develop for J as if he was the project manager. I started to treat every one of J’s ideas as something to consider seriously (and I continue to help out whenever he crosses the line with IP). I would not make any unilateral decisions, and I would run every idea I have by J. If he shoots it down, then it is done. I will come up with a different idea. And that’s the way we have worked for the last six weeks or so.  Just about every day, J looks over what I have done, plays it for 10-15 minutes, and then gives me 500 other ideas. I have been totally astounded by the level of specific detail he has been able to provide. Everything from the sound effects and music to the box art, he has had a large hand in creating.

jonah_and Me

 

 Current State

Stop The Droid! is still in early development, but we are progressing slowly. Just trying to manage the multitude of ideas that J has is like another job all by itself!
We are currently trying to:

  • Narrow the list of upgrades and weapons that will be available.
  • Decide whether or not to add “side kick” droids. (An idea J had yesterday!)
  • Decide what droids will make the final cut.
  • Incorporate the item and upgrade system.
  • Finish Multi-player coop mode

Here is a short video of Stop the Droid! in its current state.

 

BoxArt

Avatar Galaxy a last dance with XBLIG/XNA

After many months of development effort, Avatar Galaxy has finally been submitted for review. The creation of this title has been a bittersweet journey as I watch the community of developers on the XBLIG site slowly dwindle away. As I worked each day on Avatar Galaxy, I often thought back to the days when the creators club site was a vibrant community of developers who were excited  to be able to get a title on a ‘real’ console. I have also wondered if Avatar Galaxy will be the last title I develop with XNA.

Even with all its problems (such as the community review process, website and reporting issues, lack of prompt developer support) the XBLIG experience has been pretty positive, and I rather enjoyed being a part of the community. Of course we all know how to find each other on reddit, IRC, twitter etc, but there is just something that will be missed whenever the CC goes away. (I can’t put my finger on it..)

Maybe I will be able to make another title with XNA, but I probably won’t… So with that said, here are the screen shots of (Maybe my last XNA game) Avatar Galaxy

…and as Jimmy the random NPC says (with his only line in the game):  “I guess all we can do now is sit back and wait for the end.”

screen1

screen 3

screen2

screen 4

Box Art

Caching rotations as bitmapdata in flex AS3

Well what would be better for PI day then a brief tutorial on caching rotation sprites in adobe flex. While porting “Ava the Firefly” to Flex, I have encountered a bit of a snag in how the Flex framework handles rotation. In XNA, it is as simple as passing a parameter to the draw method on the Spritebatch. In AS3/Flex… not so much. The issue.. discussed here, is that performing a matrix operation to rotate a bitmapdata object once per frame will drastically impact performance in a negative way as the number of rendered sprites increases. The consensus appears to be to use a cache for the rotation information.

Here is how I handled the problem.

		static public function rotate(image:DisplayObject, degrees:Number = 0, colorTransform:ColorTransform = null):BitmapData
		{
			var matrix:Matrix = new Matrix();
			     matrix.translate(-image.width/2,-image.height/2)
			     matrix.rotate(degrees * degreeToRadians);
			     matrix.translate((image.width/2),(image.height/2))
 
			var bitmap:BitmapData = new BitmapData(image.width, image.height, true, 0x000000);
			bitmap.draw(image, matrix, colorTransform, BlendMode.LAYER, null, true);
 
			return bitmap;
		}

This will take an image an rotate it, returning the bitmapdata.
In my case, I create an array of images from a sprite sheet and build a cache of all the possible rotations of each frame in the animation.

		// Create a multidimensional array for the given index
		// ie. increment of 10 will cache all rotations in 10 degree increments (36 bitmaps)
		static public function buildRotationCache(image:DisplayObject,
                                                                       imageArray:Array,
                                                                       frameIndex:Number,
								       increment:Number,
								       colorTransform:ColorTransform = null ):void
		{
			var rotationIndex:Number = 0;
			for (var k:Number = 0; k < 360; k+= increment )
			{
				var bm:Bitmap = new Bitmap(GraphicsUtil.rotate(image , k, colorTransform));
				var gr:GraphicsResource = new GraphicsResource(bm);
 
				imageArray[frameIndex][rotationIndex] = gr;
				rotationIndex++;
			}
		}

the graphics resource class is from a tutorial found here

package
{
	import flash.display.*;
	import flash.geom.ColorTransform;
 
	public class GraphicsResource
	{
		public var bitmap:BitmapData = null;
		public var bitmapAlpha:BitmapData = null;
 
		public function GraphicsResource(image:DisplayObject)
		{
			bitmap = createBitmapData(image);
			bitmapAlpha = createAlphaBitmapData(image);
 
		}
 
		protected function createBitmapData(image:DisplayObject, colorTransform:ColorTransform = null):BitmapData
		{
			var bitmap:BitmapData = new BitmapData(image.width, image.height);
			bitmap.draw(image, null, colorTransform);
			return bitmap;
		}
 
		protected function createAlphaBitmapData(image:DisplayObject):BitmapData
		{
			var bitmap:BitmapData = new BitmapData(image.width, image.height);
			bitmap.draw(image, null, null, flash.display.BlendMode.ALPHA);
			return bitmap;
		}
 
	}
}

All for now. Happy coding..

XNA Tutorial: HLSL and SpriteBatch for 2D effects.

After writing most of my first XNA game using the built in sorting capability of SpriteBatch, I ran into a pretty big problem. I wanted to add a HLSL effect to certain sprites. I followed the instructions I found, setting the SpriteSortMode to Immediate. What I did not realize at the time is Immediate means IMMEDIATE.

spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);

This means that you cannot rely on the spriteBatch.Draw method to sort for you, and must sort yourself.

I posted in the XNA forums, and learned that it is actually better to sort yourself. This way you know exactly how everything is working behind the scenes, and you can really improve upon the look by implementing same neat HLSL effects. Rewriting my draw functionality was not a huge undertaking but it did take some time.

For my purposes, I decided to create an object for handling everything needed to draw later on.

 class DrawableObject
    {
 
        public Texture2D Texture;
        public Vector2 Position;
        public Vector2 Origin;
        public Color Color;
        public float Rotation;
        public float Scale;
        public float Z_Index;
        public Rectangle DisplayRect;
        public DrawType DrawType;
        public Effect Effect;
        public Object ObjectRef;
 
        public DrawableObject(Texture2D texture, Vector2 position,Rectangle displayRect, Color color, float rotation, Vector2 origin, float scale, float z_Index, DrawType drawType, Effect effect, Object objectRef)
        {
            this.Texture = texture;
            this.Position = position;
            this.Origin = origin;
            this.Color = color;
            this.Rotation = rotation;
            this.Z_Index = z_Index;
            this.Scale = scale;
            this.DisplayRect = displayRect;
            this.DrawType = drawType;
            this.Effect = effect;
            this.ObjectRef = objectRef;
 
        }
    }

In this Object, DrawType is an enumeration used to mark each object so drawing can be handled differently depending on its type. For my purposes I had Player, Projectile, Shadow, etc
I then create a list of DrawableObjects to sort based on the z index.

List listToDraw = new List();
 
            for (int x = 0; x < playerManager.Players.Count; x++)
            {
                    //Add all my players as drawable objects
                    listToDraw.Add(new DrawableObject(playerManager.Players[x].PlayerAnimation.CurrentTexture, playerManager.Players[x].PlayerAnimation.ScreenPosition ,                   playerManager.Players[x].PlayerAnimation.DisplayRect, Color.White, 0f, Vector2.Zero, 1f, playerManager.Players[x].PlayerAnimation.ScreenPosition.Y) / Map.Height, DrawType.Player, playerManager.Players[x].PlayerAnimation.PlayerEffect,  playerManager.Players[x]));
              }

I then sort ….

           //Sort for the right order
            listToDraw.Sort(delegate (DrawableObject d1, DrawableObject d2) {return d2.Z_Index.CompareTo(d1.Z_Index);});

and then draw the list

 for (int x = 0; x < DrawObjectList.Count; x++)
                {
                    if (DrawObjectList[x].DrawType == DrawType.Player)
                    {
                        Player pn = (Player)DrawObjectList[x].ObjectRef;
 
                        spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
                        if (DrawObjectList[x].Effect != null )
                        {
                            DrawObjectList[x].Effect.Begin();
                            DrawObjectList[x].Effect.CurrentTechnique.Passes[0].Begin();
                        }
                        spriteBatch.Draw(DrawObjectList[x].Texture, DrawObjectList[x].Position, DrawObjectList[x].DisplayRect, DrawObjectList[x].Color,
                                         DrawObjectList[x].Rotation, DrawObjectList[x].Origin, DrawObjectList[x].Scale, SpriteEffects.None, DrawObjectList[x].Z_Index);
 
                        if (DrawObjectList[x].Effect != null)
                        {
                            DrawObjectList[x].Effect.CurrentTechnique.Passes[0].End();
                            DrawObjectList[x].Effect.End();
                        }
 
                        //etc etc.
                 }

Well I hope this helps someone looking for the same thing.

~J

Photoshop takes a long time to open or create files

For that last month or so I was experiencing a rather frustrating problem. Every time I opened or created a new file, photoshop would hang for a minute or more before opening the file. I tried all the regular optimization tricks, such as defragmenting my drives, changing the scratch space and doing a memory test, but still no luck. I did search after search to try to find an answer and finally found this forum that contained the answer.

http://photo.net/digital-darkroom-forum/00KCiu

It turns out this happens when your default printer is a network printer that may be either inaccessible or has other problems. I had recently purchased a new router which uses a different local IP and had not changed the network location. Since I rarely print from that machine on my network, I did not notice that the printer was inaccessible. I simply changed my default printer from the network printer to PDF and now photoshop works as it should (quite fast). Seems like a rather odd problem for a well built application like CS3. One would think that it would check for printer issues on launch, and then ignore the printer if none exists, or if it is reporting some issue that prevents it from being properly detected. I am just glad to be able to work at a normal speed again.