Building a Tech Tree Editor in Unity

tech-tree-title

In my previous post I mentioned wanting to build a tech tree of sorts for Startup Freak. This week I started to make a list of all the possible tasks that a software startup might tackle. It soon became clear that managing a long list like that in a text file is going to become a big burden especially if want to constantly tweak and balance the list and change the dependencies between them.

In this post I’ll talk about building a quick and dirty editor in Unity that generates a JSON file to be imported into the game, and why I subsequently ditched the whole concept. If you are not technically inclined, you may want to jump to that last bit.

Tech Tree Editor Elements

Here is what the main content area looks like:

tech-tree

Items are color coded by their type (i.e. Dev, design, marketing, etc). A drag/drop motion is used to create dependencies between items, and the view is automatically refreshed so that the prerequisites of a task is always to its left. Clicking an item opens the task editor:

tech-tree-item

Dealing with Unity UI

An editor like this is obviously quite UI heavy. Unity’s new(ish) UI system seems well thought out and does cover almost any scenarios I have thrown at it so far. Having said that it definitely has a lot of quirks and it can seem quite… odd, if you have worked with other UI frameworks like HTML/CSS, XAML, etc.

A Few Random Unity Tips

Positioning Elements Programatically

This is the thing that I have found most tricky so far, given how Unity works with anchors and pivots. Here are a couple of tips:

  • While the anchors are awesome for static UI that scale correctly in different resolutions, I find that it’s far easier to do the calculations myself when I’m dynamically laying out elements. Therefore I set all anchors to the top left of the RectTransform in which I’m doing the positioning.
  • By default the UI elements have their pivot point in their center. The math can again be much simpler if you set it to the top-left or bottom-left corner. This also helped me a lot with the rotation I needed to do for the connections between the tasks (they are just thin panels)

Tab Stops

Out of the box Unity does not give you tab stops for its controls, but it does do something similar with arrow keys. In the unity editor you can set the UI elements to be selected on up, down, right and left arrows. We can use this to implement tab stops:

public void Update()
{
  if (Input.GetKeyDown(KeyCode.Tab))
  {
    var next = (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
               ? EventSystem.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnUp()
               : EventSystem.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnDown();

    if (next == null)
      return;

    EventSystem.SetSelectedGameObject(next.gameObject, new BaseEventData(EventSystem));
  }
}

Scroll Views

This is probably obvious but it did get me: as you add more items to the content area of a scroll view, and want to be able to scroll to them, you’ll need to explicitly re-size that content area (not the ViewPort).

Drag and Drop

Implementing drag and drop with Unity is actually quite easy, using the IBeginDragHandler, IDragHandler, IEndDragHandler, and IDropHandler interfaces. The only thing that stumbled me was that sometimes the drop event seemingly wouldn’t fire, because the mouse cursor was covered by another object that I wasn’t interested in (for example the connections themselves).

Remember to disable Raycast Target option or use a CanvasGroup and disable Interactable, on any elements that should not participate in the drag/drop. This may be permanent or temporary while the drag and drop is happening.

Working with JSON

If you are looking to use JSON for storing game data (which I find much easier to work with than other formats like XML or SQLite), Newtonsoft Json.NET is a pretty good choice. Be sure to use the .NET 2.0 assembly, which is the only ones compatible with Mono. Drop it in the plugins folder and away you go!

The Aftermath

Always bounce your ideas off someone else! Especially someone who thinks differently to you.

I took the list of tasks I had created and showed them to my wife, who plays her fair share of games. Granted, she is more of a casual gamer, but she was an avid Civilization 4 fan. Initially my question was, how do I clearly differentiate between tasks that are one-off (like implementing payment processing) vs ones that are ongoing (like bug fixing and feature development)?

The discussion went for quite some time. Ultimately we decided that the list I had was simply far too technical and detailed. Bearing in mind that I still want to make a game that has quite a bit of depth, there was simply too much there that you would only understand if you are working in the software development industry and would alienate a lot of players. That’s not to say those concepts cannot be dropped in the game to enrich it, but when it comes to player choice, the options have to be a lot more clear and intuitive in what they do and what result they would have.

Long story short, I have cut down the list of tasks from a 100+ tasks down to about 20 and I may cut it even further. These are very high level, things like:

  • Features
  • Security
  • Infrastructure
  • Social Media Marketing (Facebook, twitter, etc)
  • Traditional Media Marketing (TV, Radio, etc)
  • Branding

None of these tasks are ever finished. They all use a “leveling” system somewhat similar to leveling a skill in an RPG game. As you work on each of them (and you only get to work on a limited number at any given time), they level up, which in turn affects various aspects of your startup such as user signups, churn, etc.

So far from my prototypes this is a much cleaner and consistent system, and it’s a lot clearer to the player what they can/should be focusing on at any given point. And building the editor was definitely not a waste. It was a chance to learn my way around the Unity UI, and I’ll continue to use parts of it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s