Monthly Archives: October 2008

LayoutControls: LayoutTexture

LayoutTexture is very similar to LayoutSprite. It is an implementation of LayoutCapable that allows a UITexture to be used with the layout controls. After adding one to your UI you will need to either set the material or texture in the UITexture inspector.

Just like LayoutSprite, the minimum required size for a LayoutTexture is calculated from the natural size of the selected texture. If you want the LayoutTexture to be smaller than the natural size, you will need to use the Absolute Size fields. LayoutTexture will stretch to fill the space available to it when the horizontal or vertical alignment is set to stretch.

Note: LayoutTexture currently ignores the Background property.

Posted in Layout Controls, Unity | Leave a comment

LayoutControls: LayoutSlider

Note: LayoutSlider is only available in the NGUI 3.0 package.

LayoutSlider is an implementation for LayoutCapable designed to give UISlider layout capabilities.

LayoutSlider Hierarchy

LayoutSlider has three child sprites that need to be set up for use. Filled is currently required and is the look of the filled in area of the slider. When the slider’s value is 1 the filled sprite takes up the entire slider and when the value is 0 it takes up no space. Thumb is the sprite at the leading edge of the slider. Empty is the sprite that is under the Filled sprite and shows through when the value of the slider is less than 1.

When the alignment for the LayoutSlider is set to Stretch, the behavior is different than the other layout controls. When it is placing its self it will only stretch in the direction that the UISlider script is set up to go in – horizontal or vertical. For example, when the UISlider script is set up to go horizontally, the slider’s width will become the available area’s width but it will maintain its height. The thumb size will never be changed.

LayoutSlider has five properties that can be edited in the inspector on top of what it gets from LayoutCapable:

LayoutSlider InspectorValue: this is the current value of the LayoutSlider. This property can be used for two-way data binding. When the LayoutSlider script is the Binding Target of a data binding using Value the binding will be two way, when the UISlider script is the Binding Target the binding will be one-way from source.
Fully contain thumb: this is a toggle that will determine how the empty sprite is sized. If this is checked, the empty sprite will be sized large enough so that the thumb fits completely inside it, otherwise the thumb will extend outside of the empty sprite’s area. Below you can see example images that show the difference between how the empty sprite is sized based on the value of Fully contain thumb.

Slider Does Not Contain Thumb

Fully contain thumb is false

Slider Contains Thumb

Fully contain thumb is true

Slider – Empty: This is the sprite that is shows in the empty part of the slider (value is less than 0). This is already set on the prefab and should not be changed.
Slider – Full: This is the sprite that is used for the filled part of the slider. This is already set on the prefab and should not be changed.
Thumb: This is the sprite that is used for the thumb. This is already set on the prefab and should not be changed.

Posted in Layout Controls, Unity | Leave a comment

LayoutControls: LayoutInput

LayoutInput implements LayoutCapable for the UIInput control.

LayoutInput Hierarchy

Just like a UIInput, LayoutInput has two children elements that will need to be set up. The label is the text that will be shown and will need to have the font property set. The background is the graphic for the textbox and will need to be set up with an atlas and sprite.

Note that the Stretch alignment behavior for LayoutInput is different than other controls. Currently, the background will only stretch horizontally and the height of the background will always be enough to encompass the text. I made this decision to keep LayoutInput in line with how textboxes work in other environments.

LayoutInput InspectorLayoutInput only has one additional inspector property on top of what it gets from LayoutCapable: Text. This is the text value of the input and allows for two-way data binding. When doing data binding for a LayoutInput, using the LayoutInput script as the Binding Target will result in two-way binding while using the UIInput script as the Binding Target will result in one-way from source binding.

The background property is already set on the prefab, and should not be changed.

Posted in Layout Controls, Unity | Leave a comment

Plants vs. Zombies: It’s About Time – Review

I played the first Plants vs. Zombies a little bit when it came out as a flash game; it was great at destroying my wrist. Then I got an iPad and fell in love with Plants vs. Zombies. It really shines with the touch interface, it almost feels like the game was made in anticipation of tablets. Just like all the other PvZ fans out there, I got excited when I heard that there would be a Plants vs. Zombies 2 and eagerly downloaded it when it was released. It has received some very glowing reviews, which has surprised me. Don’t get me wrong, I have enjoyed playing it. I still pick it up and play it even though I’m pretty sure I’ve seen everything it has to offer right now. However, is has still left me a bit disappointed. It’s About Time seems to care more about making money than providing a great game experience. I’m going to try to break this post in half, first giving a fairly spoiler free review, then going into some more detail to give concrete examples which will contain spoilers.

It’s About Time has a considerably different feel to it than the original PvZ. There are now a number of gates, both literal and figurative, on the game play. To advance through certain parts of the game, you either have to pay money or grind out enough time in the game to continue. This completely changes the flow and feel of the game, putting the microtransactions in your face all the time. While the majority of the plants can be unlocked through play, a number of my favorite plants from the first game are locked behind a pay wall. The plants that you haven’t unlocked yet still show up in your plant selection, again putting the microtransactions in your face.

There is a great GDC Vault video by the designer of the original Plants vs. Zombies about creating tutorials. After watching George Fan talk about tutorials and really agreeing with most of what he had to say I was curious how It’s About Time implemented its tutorial. While it certainly has a different goal – to get the player into the game fast so that they can get onto the time side of the game – it doesn’t feel nearly as polished as the first game. It’s not fun. They seem to have tried to follow some of the design considerations Fan talks about, but didn’t really spend the time to fully polish them.

It’s About Time currently has three worlds, each representing a time period, that are laid out like Super Mario Bros. 3. Even though the original Plants vs. Zombies had five stages It’s About Time has a lot more personality in each of its worlds making the game feel a bit bigger than the original. The art has all been updated and the zombies are themed really well to their time periods. The game is beautiful but falls a little short mechanically – I’ll get into this more later.

Spoiler free, I don’t want to get into the cast of zombies and plants too much. I’m a bit more impressed with the new plants than with the new zombies, but I’ll talk more about this after the spoiler break. Plants now have super powers, which adds a fun new element to the game and adds a lot of personality.

I understand that game developers need to make money and I’m not against microtransactions in principle, but I can’t get past the feeling that Plants vs. Zombies: It’s About Time has far more polish put into making money than into making the game. The art has been updated and there are a few new ideas, but it feels like a mask to encourage people to pay the tolls. That said, there is still enjoyment to be had here.

[Now I'm going to talk a little more in depth about mechanics. Spoilers ahead!]

I’m going to start my mechanical discussion with stage mechanics. Each of the three time periods has its own stage mechanic: Egypt has the tombstones than certain plants can’t shoot through, Pirate Seas has a section of the ground that is not plantable but zombies will fly across the gap, and the Wild West has mobile mine carts that can be planted in. The first two of these are just a twist on things we saw in the first game, and did not really add anything interesting to the levels. The mine carts are really cool though. They really change how you think about plant placement and add an interesting feature to game play. It would have been nice if the other two time periods had similarly game changing mechanics in their levels. Maybe the pirate ships could have hard points that could be planted on and rotated, or in Ancient Egypt they could have had tomb entrances and exits that the player could open and close for zombies to walk in and out of allowing the player to control the flow of the field.

Seven to nine new zombie mechanics seems like a very reasonable number for a sequel, but only a couple of these feel really interesting. Looking at raw numbers, It’s About Time has way more zombies than the original PvZ, but many of them are rehashes of the same ideas or different skins of the same zombie. For example, in Ancient Egypt there are Bucket Zombies and Sarcophagus Zombies, but the Sarcophagus Zombie is really just a slightly weaker version of the Bucket Zombie. Many of the zombies are either slight modifications or stand ins of the original zombies. The pianist zombie is truly unique and plays nicely with the mine carts.

The plants received a bit more attention, most of the nine new plants are quite interesting. Some of them are very situationally specific and a couple of them really allow for player preference in filling a roll. For example, the Bonk Choy and Snapdragon both offer excellent front line defense. I prefer the Snapdragon, but both fill the roll very well and both in interesting ways. While I would like to see some plants that really change up the mechanics of the game, I’m pretty happy with It’s About Time‘s offering. I also really enjoy the addition of the plant food. It acts as a bit of a “get out of jail free” card, allowing the player to unleash a powerful attack when things are looking grim. I really like an addition like this for giving the player a little bit more to do in the game, but not so much that the amount of actions that the player needs to take is overwhelming.

In writing this, I’ve thought a lot about the place of microtransactions in games, and might write a full post on my thoughts. In brief, I think It’s About Time uses them too much as a gate for content instead of using them to make the game more interesting for those who are willing to pay. I think this this the wrong way to go about a microtransaction implementation.

Posted in Game Review | Leave a comment

Layout Controls Live!

Exciting news! My first package has been accepted by the Unity Asset Store! Here’s a link. Layout Controls is live and I’ve set the price at $20. I have no good idea on how to price this, but $20 seemed reasonable. Maybe I’m wrong.

I will, of course, be giving support on my forum (which really needs a visual upgrade), and updating the package as often as it needs to fix any problems that are found. An overview and documentation can be found here. Except for the next two days. I am going on a short trip and will not be near a computer for the next couple of days – until Oct. 9.

I’m really excited and hope that people find the Layout Controls package helpful!

Posted in Layout Controls, Unity | Leave a comment

Tomb Raider

I had a couple goals for the Steam Summer Sale this year. There was a lot of anticipation, controversy, and then rave reviews for the most recent Tomb Raider game, so it was on the list of games I had to buy if it came on sale. It did and I did. I don’t regret it at all. There will be some minor spoilers in this discussion. I don’t talk about any major plot points, but if you don’t want to know anything about where the game goes, avoid reading farther.

Classically, Tomb Raider has been on consoles and does not generally require a lot of twitch shooting so I decided to play with an XBox360 controller. It worked great. The controls are very tight; everything working as I would expect it to, and I very rarely had instances where the game did not perform the action that I expected it to given my input nor did I ever really fumble with the controls, forgetting how to execute something. Lara’s movement is quite fluid, using context sensitive button presses to execute her various options. I did have trouble understanding some of the combat contexts sometimes, I still don’t know how to execute someone in a dodge-strike attack rather than just stabbing their knee. This is a very minor gripe though, every time I was in melee combat it was because I decided to be. I never felt like I had to be in the situation where I needed to get an execute, but only managed to hit someone in the knee.

The game does a great job setting the characters up. Lara is a greenhorn to this exploration business, but it is definitely in her blood. The more experienced in the group don’t completely trust her but she has great intuition. This really solidifies the feeling of barely surviving through the ordeal that is to come. Her first weapon is a makeshift bow and arrow that she has made out of the local vegetation, reinforcing the survivalist attitude. I was disappointed at how quickly the game shifts away from this feeling. Getting a pistol, given the situation on the island, makes some amount of sense, but Lara quickly gains a shotgun and automatic rifle. As far as I’m concerned, if you’re carrying a shotgun you’re no longer in survival mode. I made an effort to preserve the survival feeling by using the bow as more often than anything else, but if you give me a shotgun I’m going to blow some people up. I would have appreciated a much slower transition from survival to offensive. Lara very quickly becomes a mass murderer in this game with a fairly high body count – easily over 100. This doesn’t seem to fit with the tone set at the beginning.

The game makes a compelling argument for Lara’s actions. I was definitely drawn into the story, and the virtual killings didn’t seem too ridiculous while I was playing. However, I was frequently pulled out of the story by the collection mechanic. Each area in the game has at least three different sets to collect. Now I realize I could just ignore these, and play through as if they weren’t there, but they are always in your face. You find a map and it shows you where they are, you pull up your menus and it tells you how many you’ve found, you collect one and it tells you you will get a bunch of experience if you complete the set. This all pulls the player out of the story and gives the player chores around the island. It ruins immersion. I think taking the metrics out of the game would have been enough to preserve the immersion. This is my biggest gripe with the game, it pulled me out of this beautiful world that I was trying to survive in to tell me, “Hey! Go find that thing over there!” Don’t do that. If I find that thing over there, great! If I don’t, oh well, it wasn’t a part of my story. However, I really liked one of the collections and it tied into the Tomb Hunter theme really well.

I didn’t notice it too much while playing but looking back, the game’s platforming puzzles were a bit weak. There are segments that are definitely platformer puzzle like but none of them seemed to have failing conditions. They were all remarkably straight-forward after all of the components had been seen. The game masked this quite well by making the environments fairly interesting feeding the exploration desire. However, there weren’t places where trial-and-error would have produced many (or any) errors or mechanisms to decipher. I think the game went right up to the line that would have made segments puzzles, but didn’t cross it.

The game wonderfully wraps back around to the other tomb raider games, sticking in bits of nostalgia here and there to really give Lara an origin story. Even though it was obvious what was going on, it still felt subtle. This is definitely a game to play, and if you’re a Tomb Raider fan a must play.

Posted in Game Review | 2 Comments

Layout Controls: An Overview

Videos:
Getting started video.
LayoutTable Demo

Layout Controls are Live! The goal of these controls is to simplify the creation of complex or dynamic user interfaces by having the UI elements place themselves based on the area available to them and respond to changes via data binding. Short descriptions and links to longer documentation for the layout components can be found at the bottom of this page. Support can be found in the forum. Currently the controls build on top of NGUI, but I am planning on updating the package with a set of controls that support Unity’s new GUI system when it releases.

At the core of this plug-in is an abstract base class called LayoutCapable. All controls involved in layout, such as LayoutStackingPanel and LayoutTable, inherit from this. There is also an implementation of LayoutCapable for display controls, like LayoutLabel and LayoutButton, so that they can be laid out properly. When layout occurs, the top level control – that is, the children of the NGUI Panel – will use the entire screen as its available area. Every child will be given the area available to it based on the various ways in which the controls perform layout.

All LayoutCapable implementers will have eight fields that can be edited in the Unity Inspector. The first of these is Visible which controls whether or not the control is shown. This should be used instead of toggling the objects enabled state.

I took a Box Model approach to layout, similar to how elements are laid out on a web page or in XAML. Three of the eight of the editable properties from LayoutCapable directly relate to the Box Model I implemented. Here’s a graphic of how you can expect controls to be laid out and size, notice that I do not include a border:

Box Model

  • Margin: Empty space around the control.
  • Padding: Empty space between the edge of the border and the control’s contents.
  • Background: This is one of the children of the control, probably a UISprite, that will be used as a background. It will be sized according to the amount of space used by the control, the margin, and the padding. Background is not required, controls will work just fine without this set.

The next two editable properties change how a control is placed within the space available to it:

  • Horizontal Alignment: This has four possible values: Left, Center, Right, and the default value Stretch. Stretch means that the control will take up all the space available to it. If this is set to Left, Center, or Right the control will take up the minimum amount of space required and will place its self in the corresponding location within the space available.
  • Vertical Alignment: This has four possible values: Top, Center, Bottom, and the default value Stretch. This behaves the same as Horizontal Alignment, just in the vertical direction.

Below is an example of a button in different horizontal by vertical alignments with a margin of 10 pixels in all dimensions, left and right padding of 10 pixels, and top and bottom padding of 5 pixels :

Alignments

The last two editable properties of LayoutCapable override the layout mechanisms:

  • Max Size: If one of these values (width or height) is non-zero, it represents the maximum amount of space in that dimension that the control will use. If the control’s contents need less space than the Max Size, then the control will only use as much as is needed. If it is zero, it is ignored.
  • Absolute Size:  If one of these values (width or height) is non-zero, the control will use the value for the its size in that dimension, regardless of how big its contents are. If it is zero, it will be ignored.

Layout Controls comes with a bunch of implementations of LayoutCapable split into controls that perform layout and the visual controls that are the real content. Each of these has a corresponding Prefab that should be used in the creation of UIs. Here they are:

Perform layout:
LayoutStackingPanel - places elements next to each other
LayoutTable - places elements in rows and columns
LayoutTabPanel - places elements in tabs, with only one tab visible at a time
LayoutScrollViewer - places elements in a scrolling area

Visual:
LayoutLabel
LayoutButton
LayoutSprite
LayoutTexture
LayoutCheckBox
LayoutInput
LayoutSlider – NGUI 3.0.4 and later.

Miscellanious and Utility:
Bindable
DataBind
ItemsControl
ObservableCollection
UIStateManager

Posted in Layout Controls | 2 Comments

Layout Controls: LayoutSprite

LayoutSprite is an implementation of LayoutCapable designed to give NGUI UISprite layout functionality. The UISprite component will need to be set up just like any NGUI UISprite with an atlas and sprite.

LayoutSprite uses the sprite’s natural size to represent its minimum required space. This means that if you want to shrink the sprite, you will need to set the size in the Absolute Size fields. However, when horizontal or vertical alignment are set to “Stretch” the LayoutSprite will resize to fill the space available to it.

Note: LayoutSprite does not currently support the Background property.

Posted in Layout Controls | Leave a comment

Layout Controls: LayoutLabel

LayoutLabel is an implementation of LayoutCapable meant to give UILabel from NGUI layout functionality. Since LayoutLabel uses UILabel to display text, the UILabel needs to be set up with a Font before it will show anything. It has one property on top of what LayoutCapable has: Text Alignment.

LayoutLabel InspectorText Alignment sets how the text is positioned in the space available to the control, but does not affect the size of the control. It also changes how multi-line text justifies.

Note: currently background is not implemented for LayoutLabel.

Posted in Layout Controls | Leave a comment

Layout Controls: UIStateManager

UIStateManager is a component that handles showing and destroying UIs based on what requested the UI to be shown. It is only one possible solution to this problem and is being provided as an example of a way to centralize and decouple the display of UIs from components that need UI displayed.

The core idea behind UIStateManager is that components will ask it to display UI instead of creating and displaying UI themselves. A component that needs to display some UI should get a reference to the UIStateManager in the scene, and call ShowUIFor when it needs to show UI, passing itself and the object to use as a data context for the UI as arguments. With UIStateManager if ShowUIFor is called when there is already an open UI, the currently open UI will be hidden so that there is only one visible UI at a time. UIStateManager handles the creation of the UI objects and will assign the data context to the top level Bindable component if it exists.

There are two ways to close a UI with UIStateManager. CloseUIFor will close the UI that was opened when ShowUIFor was called with the same MonoBehaviour argument. CloseUI takes the Transform of the UI that should be closed as an argument. After a UI is closed, UIs that were hidden by multiple ShowUIFor calls will be shown again in the reverse of the hiding order.

UIStateManager also has two events: UIOpened is fired whenever a UI is opened and UIClosed is fired whenever a UI is closed. UIOpened is an Action<MonoBehaviour, Transform> which means that any void method with a MonoBehaviour and a Transform argument can be attached to it. It will be called with the MonoBehaviour used to show the UI and the root Transform of the shown UI. UIClosed is an Action<MonoBehaviour> and will be called with the MonoBehaviour used to open the UI.

UIStateManager InspectorUIStateManager should be added to the top level Panel of the NGUI UI because it creates all requested UIs as children. To create a new managed state, drag the UI Prefab into the box under “Add new UI State”. This will create a box representing the State, where activators for that State can be added. Activators can be added to a State in the same way that a State is created, just drag the MonoBehaviour that ShowUIFor will be called with into the box under “Add Activator.” Activators can be removed from the State by clicking the ‘x’ on the right side of the State box. States can be removed by clicking the ‘x’ in the upper right of the State box.

Posted in Layout Controls | Leave a comment