Alpha Accesswebsite_badges_steamwishlistwebsite_badges_steamwishlist

Tiled map tools with Unity


The arrival of Unity 4.3 brought solid 2D support. Though some issues are being fixed with dot releases and some support is still outstanding, it already provided a solid foundation to prototype (and continue development on) this project. Without giving too much away, one thing that I needed from the outset was an easy way to build tile-base maps quickly, with variable flexibility.

Of course, I began researching existing tools, which are quite mature at this point. One of the favorites is Tiled, and another relative newcomer is Pyxel Edit (which I’ve been using for design and animation production). Getting Unity to play with Tiled was pretty painless and surprisingly simple. I saved my Tiled maps in .json format, and wrote a simple loader (using SimpleJSON) that would import a map into my project. Here’s some example code for the importer:

public void LoadMap(string mapPath)
{
	// read in and parse the .json map file exported from Tiled
	TextAsset mapData = (TextAsset)Resources.Load(mapPath);
	JSONNode json = JSON.Parse(mapData.text);
	
	// bitmasks defined from the Tiled map format specification
	uint flippedHorizontally = 0x80000000;
	uint flippedVertically = 0x40000000;
	uint flippedDiagonally = 0x20000000;

	int width;
	int height;
	int row;
	int column;
	uint tileID;
	int tileIDOffset;
	float xscale;
	float yscale;

	// for each Tiled layer
	for (int layer = 0; layer < json["layers"].AsArray.Count; layer++)
	{
		// get the width and height of the layer (in tiles)
		width = json["layers"][layer]["width"].AsInt;
		height = json["layers"][layer]["height"].AsInt;
		
		// for each tile in the layer
		for (int i = 0; i < (width * height); i++)
		{
			// pull the tileID, and use bitmasks to determine any transformations
			tileID = json["layers"][layer]["data"][i].AsUInt;
			xscale = ((tileID & flippedHorizontally) != 0) ? -1.0f : 1.0f;
			yscale = ((tileID & flippedVertically) != 0) ? -1.0f : 1.0f;
			tileID = (tileID & ~(flippedVertically | flippedHorizontally | flippedDiagonally));

			if (tileID != 0)
			{
				// get tile information
				tileIDOffset = json["tilesets"][0]["firstgid"].AsInt;
				row = (int)(i / width);
				column = (int)(i % width);

				// do stuff pertaining to your game with your tileID here
				// ...
			}
		}
	}
}

The issue I had with these (and most other) tilemap editors is that they are based on single tilemap image atlases. This is understandable for their purpose, but it also assumes that during an entire development cycle, your tilemap shouldn’t change and is complete from the start. If you have a bunch of maps based on a certain image atlas, the entire system becomes fragile. Unless you are simply adding new sprites, you don’t have the option of rearranging tiles, or replacing content, without affecting all maps based on it. Not only that, but Unity Pro supports automatic image atlasing, which means my tilemap image shouldn’t have to be pre-determined – I don’t need a tilemap atlas. I needed an editor that was based on soft-links to tiles, and in Unity’s case, prefabs.

I began exploring the notion of creating my own editor panel, and in just a few days, I had a completely working, flexible prefab-based tile editor that suited my needs perfectly. The nice thing about this is that it is easily extendable to support more features that this specific project requires without finding workarounds using other tools, or being “locked in” to a specific workflow.

Custom prefab-based tiled map editor using Editor Window in Unity.

Custom prefab-based tiled map editor using Editor Window in Unity. I know it’s weird that the “Bottom” layer is actually on top. :)

Some research brought me to an excellent tutorial by Daniel Branicki for tuts+ with the basics of creating your own editor window, drawing a grid, and snapping prefabs to the grid. I started my work extending Unity’s Editor Window class using this tutorial as a guide, and here are just a few notes that might help you in your tools:

DrawLines()
Rather than use the Gizmos.DrawLine() method, I used Handles.DrawLine() instead. The reason is that Gizmos.DrawLine() seems to be called continuously, slowing down execution, and if you draw transparent lines they quickly stack to create solid lines.

Clean OnGUI()
I like to break out my OnGUI() code into functions based on sections of the UI, for easier editing and maintainability. As an example, you can see how these match up to the UI screenshot above:

void OnGUI() 
{
    SectionFileOperations();
    SectionMapInformation();
    SectionLayers();
    SectionSettings();
    SectionTools();
    SectionTiles();
}

Easy Layers
My “layers” are based on Unity’s Renderer.sortingOrder. This is just a series of GUILayout.Toggle() controls that map to sortingOrders .

Respond to the Scene
To listen for input and respond to events in the Scene window (in my case to “paint” with prefabs and use keyboard shortcuts to activate tools), you need to add your Editor Window class as a delegate to OnSceneGUI, then implement the OnSceneGUI() function for your custom logic.

void OnFocus()
{
    SceneView.onSceneGUIDelegate -= this.OnSceneGUI;
    SceneView.onSceneGUIDelegate += this.OnSceneGUI;
}

void OnDestroy()
{
    SceneView.onSceneGUIDelegate -= this.OnSceneGUI;
}

void OnSceneGUI(SceneView sceneView)
{
    // custom scene & drawing logic here
}

Snap to Grid
In your Update() function, you can easily snap the selected object to a grid by setting the Selection.transforms position:

private Vector3 Snap(Vector3 point)
{
    Vector3 snappedPoint = new Vector3
    (
        (snapValue * Mathf.Round((point.x / snapValue))),
        (snapValue * Mathf.Round((point.y / snapValue))),
        (snapValue * Mathf.Round((point.z / snapValue)))
    );
    return snappedPoint;
}

void Update()
{
    foreach (Transform transform in Selection.transforms)
    {
	    transform.transform.position = Snap(transform.transform.position);
    }
}

What’s in a name?


Some good and not-so-good ideas here...

Some good and not-so-good ideas here…

While working on the Unity prototype, I was keeping a running list of potential studio names in the background. It might not seem important this early on, but having a name and logo solidified gives me a “foundation” or “home” to nurture the project along. I also wanted to register the domain and set up this blog to keep pace with development without getting too far behind.

In fact, that will most likely be a running theme here. It’s common advice to not get bogged down in details / rendering / polish too early, but I think there’s a gray area there that needs to be explored. If you only work on foundation and roughs, it can sometimes lead to exhaustion since you don’t see the “fruits” of your labor. I think a little bit of continual polish keeps your excitement level up for a project – and that’s just as important as anything else in long dev cycles. If you feel like a little polish and it’s not conflicting with your immediate needs or development schedule – go for it! It’s healthy.

I definitely understand the argument that a company name isn’t that important and it’s the quality of product that (mostly) determines success, but it’s important to me. I had some criteria:

  • Concise: I didn’t want something too lengthy. I’ve always been partial to short names, though this can make it difficult to choose something that hasn’t been taken. Sombr is definitely concise, and dropping the “e” – while a little Web 2.0ish – helps keep it unique. A quick search didn’t turn up any “Somber” game studios or conflicting interests.
  • Easy to say: I didn’t want to have to repeat my company name a few times during introductions. For some reason, that always weakens it for me. I liked some of the names on my potential list quite a bit, but they just didn’t roll off the tongue. A little bit of alliteration goes a long way, and some of these names had an uncomfortable cadence between the words.
  • Easy to spell: I know, I broke this rule. But hey, the missing “e” gives it character, right? Excuses, I know. That’s ok – I’m alright with 4/5 of my naming criteria. Secretly, I’m not ok with that, but don’t tell anyone. Truth be told, it’s still easy to spell, but it does require a quick disclaimer when spoken. Hopefully I don’t regret this. :)
  • Domain availability: I’ve never been a fan of .nets, dashes in domain names, or attaching “games” to the domain because the company name alone is taken. I know, it’s nit-picking, but if I can avoid that, now’s the time. Luckily I had already owned sombr.com for a previous idea that I couldn’t get too, so I resurrected it.
  • Meaning: This is probably the most important criterion and it certainly goes without saying, but your company name should definitely mean something to you. Have integrity and put your all into everything you do; you should be proud of the home that the rest of the world sees from the outside, and imagine that the company is always a reflection of your values. Sombr means many things to me, some personal and some not. In a casual sense, I’ve always liked sad / melancholy / pensive works of art and music, and I’ve also believed that sadness can be just as “positive” as happiness in that both experiences are powerful and emotional, and worth feeling. This doesn’t mean our games have to be sad. :)
Sombr logo iterations

Sombr logo iterations

I worked on many iterations and sketches to settle on a logo design. What you see here is the last batch after I had already settled on typography and a general “flow” of the elements that make up the design. You can see that I had some elaborate trim and eventually arrived at something more simple. I liked some of the explorations in the first column, but they also felt a little immature and impulsive; I could just “feel” myself losing the trim years later and being much more satisfied with the simplicity, so might as well cut the fat now. As I progressed I made some minor variations to the type, such as removing the large gap between the “M” and the “B” and adjusting the swirly tails. For those that are interested, this is based on a modification of the Rebucked font by UnAuthorized Type.

I actually liked the original stand-alone version, but also wanted a recognizable, iconic element that could stand on its own without the type. The little wedge shape above the “M” lent itself well for imagery placement, so I explored some options here. I loved designing all these little icons, but some didn’t make sense with the “somber” theme. In the end I settled on the candle flame. It fits the mood perfectly, has a pleasing shape, and is also vague enough so as to avoid pigeon-holing the company in future projects.

These final images are actually all high-resolution. This is just a scaled-down version for this post.

These final images are actually all high-resolution. This is just a scaled-down version for this post.

As a final step, I created low-resolution pixel versions of the logo and icon at various sizes. “Nearest neighbor” scaling in Photoshop is your best friend here to preserve hard edges without anti-aliasing, but there are really no shortcuts. It rarely works to just scale down a vector or high-res image for pixel art – a common rookie mistake. You can start with a scaled down version as a rough guide, but it’s best to intentionally trace or redraw images using the pencil tool for best results. You can see that the flame, swirls, and general letter stems needed special treatment to read properly at very small sizes. Attention to detail is a virtue!

I hope you enjoyed this rundown of name to logo, and it gives you some inspiration for your own company name!

New beginnings


adhesive_shelf

void Start()
{
	Debug.Log("Hello, world!");
	SpendLifeSavings();
}

A big, excited, “Hello” from Sombr – an independent game developer focused purely on fun gameplay, integrity, and respect for the player’s intelligence. A little bit of background:

I’ve spent the last (almost) three years working at Adhesive Games on Hawken. This was an incredible, interesting, roller coaster journey, and I’ve had the pleasure of working with some amazingly talented individuals and just all-around good human beings and friends. I was responsible for sound design & implementation, music (with my production partner for Paper Sound), and the in-game HUD UI (design & ActionScript development). The dev team remained relatively small, allowing everyone to contribute in a major way. While this necessitated some crunch madness, it also fostered some pretty fast personal growth and experience.

Prior to Adhesive, I worked on a lot of Rails web development over the years, but my heart was always in games and I released a few iOS titles as learning/side projects. About a year ago I started working pretty heavily on a new iOS game project. However I wasn’t able to focus enough time on it as most of my time was occupied by Hawken development, and a couple other apps with the same idea beat me to market. Though I believe I could have executed on the original idea in a way that would have stood out, I also started dabbling in Unity around this time and I was completely hooked.

Unity seemed to combine all the gears of the way my brain works into one package. The ability to rapidly prototype reminded me of “sketching” with Processing, and the accessibility of attaching behaviors to game objects with simple scripts sold me. I believe to get the best possible gameplay experiences, you need tools that allow you to experiment freely and iterate with ease, and any barriers to this allow designers and developers to “settle.”

About six months ago I had an idea for a local two-to-four-player arena game with a twist, and an initial proof of concept prototype took just a few days to complete in Unity. It’s my extreme pleasure to now be focusing 100% on this project, with all the excitement, danger and hurdles that lie ahead. While I’ve worked on my own projects before, this is the first time I’ve been completely independent without another gig “floating” these ideas. I’ll be self-financing this, which is liberating and frightening at the same time.

One goal is to keep a running developer diary of the progress. I’ll have to be careful to not reveal the core mechanics of the game (until it’s ready to announce), but I think it won’t be too difficult to skirt around it while still providing some development anecdotes. I hope to post frequently during development with bite-sized findings and Unity techniques, including code, graphics, and audio examples along the way. I may not do things the best way, but this is a learning journey, and comments and feedback are most appreciated. I hope this will be of interest to you guys out there… join me on the adventure!

©2017 Sombr Studio LLC