Skip to content

Unity: Debug.Log console messages with timestamp

While Unity is packed with professionalism all over, the one thing that is astonishingly basic is the output of debug messages to the console log. Until these days there is really not much you can configure or customize here. It is like it is. And that looks like that:

UnityConsoleWithoutTimestamp

What I really missed is at least a proper timestamp. For one it prevents the aggregation of identical message (I never understood what that would be good for, but maybe that’s just me…), furthermore you can check how current the latest entry in your log is. I think it is not even necessary to explain why that is useful. Every other log in the world would have timestamps for each entry, so we want our log to look like this:

UnityConsoleWithTimestamp

Actually this is pretty easy and not much more than a bit of routine work. Since I did it already, you don’t have to. Unitys Debug class is declared as sealed, so we can’t just inherit from it and overwrite what we need. Instead we just define a new class named Debug. It will cover the original one  and call ours (as long as someone didn’t fully qualify a call with the UnityEngine namespace, which you would normally not do anyway). We just prefix it with the desired format of a timestamp (the code contains already one alternative for you to play with) and call the original log function. And done.

But just wait: since your new Debug class will catch all functions of the original class, you have to do a bit more tedious work to mirror all of them and route them to the Unity implementation, if it should work seamlessly. Lucky you…I did that as well. So just download the C# class and drop it into your script directory, and you are instantly enjoying timestamped log messages without any additional work.

Using Unity Toolkit 2D and LeanTween

Even with Unity 4.3 and its latest 2D features, I am sure a lot of you still use the great 2D Toolkit on top of it. It has so much more great features that Unity does not offer (or only for Pro). For tweening, I use LeanTween, because it has great support and ― nomen est omen ― really operates very slick and lean. The one thing that I found a bit tedious is applying two of my most used tweens: alpha and scaling. Both can’t be applied in the regular fashion on the game object, but should rather be applied directly to the sprite component. So you need to fiddle around with LeanTween.value and write all the same code over and over to accomplish what it takes to do that properly. This also really messes up the code, so I created a nice helper that makes it really easy to do alpha and scale tweening directly on a sprite. All you need is the latest LeanTween (>= V2.031), since it offers some great new features that you’ll need to do that. If it’s not yet available on the Asset Store, you can always grab the latest version directly from Github.

Just create a new script named LeanTweenExtension.cs with the code below or download it ready-made. Then you can simply append setSprite() to your LeanTween alpha or scale statement, and the operation will be applied to the sprite component rather than to the gameobject. Everything else (looping, easing, …) works exactly the same as before. There are just two catches:

  • You can’t use your own onUpdate function on that tween, since it is already needed internally to do the magic
  • You can’t scale separate x/y/z values at the same time using LeanTween.scale. While you can (and need to) provide the scale as a Vector3 parameter, only the x component is used and applied to x and y at the same time. This is probably the 90% use case anyway, but if you need to do it separately, you can just use separate and consecutive LeanTween.scaleX/Y/Z  calls to achieve the same (The reason is that the LeanTween generic callback function that is used internally here just tweens on a single float, not a vector)

There are two signatures to call: setSprite() and setSprite(tk2dSprite sprite). The first will lookup the tk2dSprite component on the tweened gameobject, with the second you can provide it explicitly if you either tween on  a different gameobject that does not own the sprite, or if you simply have it at hand and want to save the additional lookup time. Call it like this:

  // shrink sprite to half size in one second
  LeanTween.scale(gameobject, new Vector2(0.5f, 0), 1f).setSprite();

  // pulse another sprite (fade in and out repeatedly) with a second frequency, but tied to the same tween gameobject  
  LeanTween.alpha(gameobject, 0, 1f).setSprite(anotherSprite).setLoopPingPong().setEase(LeanTweenType.easeInOutSine);

  // etc. ;-)

So as you can see, you can write very clean code even for complex tweens on your sprites. You can of course extend this helper extensions for other operations, but as far as I needed them up to now, these are the two that need special attention when used for sprite gameobjects.

And here is the beef:

using UnityEngine;
using System.Collections;

public static class LeanTweenExtension {

  // Extend LeanTween to operate on a tk2dsprite rather than the gameobject
  public static LTDescr setSprite(this LTDescr ltdescr, tk2dSprite sprite) {

    if (sprite == null) throw new UnityException("LeanTween.setSprite(): no sprite provided");

    switch (ltdescr.type) {

    case TweenAction.ALPHA:
      // set alpha directly on sprite color
      ltdescr.setFrom(new Vector3(sprite.color.a,0,0));
      ltdescr.setOnUpdate(delegate(float alpha, object tk2dspr) {
        Color col = ((tk2dSprite)tk2dspr).color;
        col.a = alpha;
        ((tk2dSprite)tk2dspr).color = col;
      }, sprite);
      break;

    case TweenAction.SCALE:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(scale, scale, sprite.scale.z);
      }, sprite);
      break;

    case TweenAction.SCALE_X:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(scale, sprite.scale.y, sprite.scale.z);
      }, sprite);
      break;

    case TweenAction.SCALE_Y:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(sprite.scale.x, scale, sprite.scale.z);
      }, sprite);
      break;

    case TweenAction.SCALE_Z:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(sprite.scale.x, sprite.scale.y, scale);
      }, sprite);
      break;

    default: throw new UnityException("LeanTween.setSprite(): action not yet supported " + ltdescr.type);
    }

    // make sure onUpdate is not set, otherwise object callback will not be called
    ltdescr.onUpdateFloat = null; 
    // change tween type to generic "value" callback
    ltdescr.type = TweenAction.CALLBACK;

    return ltdescr;
  }

  public static LTDescr setSprite(this LTDescr ltdescr) {
    if (ltdescr.trans == null) throw new UnityException("LeanTween.setSprite(): no gameobject set");
    tk2dSprite sprite = ltdescr.trans.GetComponent<tk2dSprite>();
    if (sprite == null) throw new UnityException("LeanTween.setSprite(): no sprite component found");
    return ltdescr.setSprite(sprite);
  }
}

Creating a button animation with UIToolkit (Unity)

If you played already Café International for iOS (and seriously: you should!), then you might have noticed a special user interaction feedback throughout the game: buttons and other touchable elements jump a bit up and come back with a nice spring effect, plus a little fancy glitter particle effect. It gives just another way of interaction feedback that I personally like very much (which is why I did it that way😉 ).

I wanted to have that now also for something I am doing with Unity, and fortunately the very flexible free UIToolkit add-on makes it really very easy to implement the exact same behavior. Since such an element generally also behaves like a button, we simply derive a new class UIJumpingButton from UIButton. With such a modified button you can do everything you could also do with a normal button: add touch up/down/move events, attach a sound, etc. In addition, there is a new touch event OnTouched that will only fire once the animation is completed and the button is back in place. You can decide then whether you want to fire something straight on the first touch (via OnTouchDown) or rather when things are settled again.

To achieve the jump effect, we just add some code in the onTouchEnded handler. So if a user touches the button it get’s highlighted, but he can still move the finger outside the button and release without anything happening then. Just if he releases inside the button, it will fire. We then apply a chain of two animations: jumping up a bit by a certain percentage of the screen height, and then falling back to the previous position with a slight bounce. When all is done, we fire the OnTouched callback, if set. Furthermore, we don’t allow another touch animation while the ongoing animation isn’t completed yet. And that’s basically all the magic to it.

This is how you would use jumping buttons:

UIJumpingButton b1 = UIJumpingButton.create("start.png", "startSel.png", 0,0);
b1.positionFromTopLeft(0.5f, 0.33f, UIyAnchor.Center, UIxAnchor.Center);
b1.onTouched += ( button ) => Debug.Log("Start pressed");

UIJumpingButton b2 = UIJumpingButton.create("options.png", "optionsSel.png", 0,0);
b2.positionFromTopLeft(0.5f, 0.66f, UIyAnchor.Center, UIxAnchor.Center);
b2.onTouched += ( button ) => Debug.Log("Options pressed");

And this is a video of what you’ll get then:

I compiled this sample as a unity package for you to download and try it out, plus you can grab the UIJumpingButton.cs class file and the ButtonGlitter prefab for the particle push effect from this download. It does also contain the current UIToolkit runtime, so it should run right away in any Unity project. If you want to test it inside a project that already contains UIToolkit, please delete the UIToolkit folder from my sample.

To get it going, just import it into your current or a new unity project and load the included demo scene then.

You can change the glitter prefab to any other style you like. Just experiment with the settings or the particle image − it’s fun! Or just switch it off, it you don’t like it at all. When you want to test it in the editor, just pull the prefab into your scene, so you can easily have it emit with a simple mouseclick and watch your changes instantly. Make sure to design the particles at low-res (use a small editor window), because the settings are automatically scaled up for higher retina resolutions at runtime and are expected to be set for low-res in the prefab.

Using Bitmap Fonts for UIToolkit (Unity)

When you need to present text with UITookit for Unity − and for sure you’ll need that sooner or later − you have to use a bitmap font, so a fixed rendered image of all characters of a vector font (like a True Type font) you would normally use. First of all you need a tool to create such an image of a vector font. For Windows, there is a free tool from Angelcode, and for the Mac you can use the free Hiero. Both have it’s ups and downs, but hey − they are completely free. I did not get along too well with either of them, but maybe you have more patience to try them out.

If you are willing to pay a bit, then for the Mac there is the excellent but a bit more expensive Glyph Designer, and what I found lately and use now is the excellent and very easy to use BMGlyph tool (around $10), which I explain from here on.

Once you started BMGlyph, just select an already installed font or load a vector font explicitly by clicking the folder bottom right of font selector list. Now perform the following settings:

  1. Choose the font size to render. That should be the largest font size you plan to use, multiplied by four to create the largest resolution for iPad retina screens. So if your largest font is 24px, select 96 here. If you need a lot of much smaller font sizes also, you should consider to render an additional smaller font, because a small font will look better if rendered at that size, rather than just being scaled down.
    In the lower left character box, you can enter all characters you’ll need to support the different languages you need. You can preselect Basic Latin and Latin Supplement special characters (like German Umlaute), but you can also add them manually or edit the preselection.
    bmGlyph1
  2. bmGlyph3bmGlyph2Set the fill color to white, because otherwise you can’t change the color programmatically later on
  3. Try to not use fancy stuff like shadows, font outlines (stroke) or gradients, because they won’t scale well for lower resolutions or text sizes. So switch or leave off all the other settings if you don’t ned them badly. If you use them, check critically how your fonts look on all target platforms and in all final text sizes.
  4. Let the texture size be optimized through the Auto Size setting, because it will produce the smallest possible graphics, so we don’t waste too much space later on in our Texture Packer sprite sheet.
  5. Use Publish to start exporting the files we need. This is the hires texture rendering, plus three metadata files for the font information for each resolution. The first export setting called Default is already there. Set the target directory and name as you wish, and the suffix to 4x. Choose Unity as the format. Then select the Default entry and click the 50% and the 25% buttons on the lower left. For the 50% export, uncheck the texture export (only coordinates required) and set the suffix to 2x. For 25%, uncheck the texture also, and clear the extension.
    bmGlyph4
    bmGlyph5
    bmGlyph6
  6. Click Publish to export the hires image and three font files. The three font files need to go into a folder hierarchie below a Resource folder. For the image, remove the 4x extension again (I hope this won’t be necessary for future version of BMGlyph) and move it to your hires sprites for Texture Packer.
  7. Create a new set of spritesheets with Texture Packer, now containing also your bitmap font (I don’t explain using Texture Packer here, but it is explained on the UIToolkit page). It is important to have all your menu sprites and the font in one final texture to assure just one draw call for the GUI stuff, one of the major performance advantages of UIToolkit. Texture Packer will also create your 2x and lowres spritesheets also.
  8. To make your fonts (and other UIToolkit GUI sprites) look laser sharp and crystal clear, make sure to set all Unity spritesheet import settings to Texture Type: GUI and to Format: True Color (compressed will end up in very ugly, blurry artefacts).

Might look a bit confusing and like a lot to do, but the whole workflow is really easy, and once you did it for the first time, it is really a no-brainer.

Now all you need to do is load the font once with the UIText class, and with that you can create as many different UITextInstances as you like.

  // Some gameobject startup code
  void Start () {
    UIText fnt = new UIText("MarkerFelt", "MarkerFelt.png");
    UITextInstance text = fnt.addTextInstance("The quick brown fox", 20, 20);
    text.setColorForAllLetters(Color.yellow);
    UITextInstance text2 = fnt.addTextInstance("jumps over the lazy dog", 20, 60, 0.75f);
    text2.setColorForAllLetters(Color.red);
  }

Each text instance can have a different size by simply setting the textScale property (and better don’t scale it up − it’ll look ugly then if you use a valu larger than 1.0f). You can also change the color, and even each single letter inside of it can be set to a different color by providing a color array information. The right resolution will automagically be loaded from the spritesheets via the resolution extension mechanism (4x, 2x, -).

bitmapFont1

With these simple steps, you can now find your right font and use it in your Unity games. However, here is one final word of caution on free fonts: do read the licensing agreement of those fonts. Free fonts are rarely really free to use in games or other software. Usually they are only free to be used for producing printed or electronically published texts, sometimes also free to be used on websites. So make sure the license agreement explicitly lists usage in commercial software (like for the nice Junction font). And if specifically asked for, don’t forget the proper credits (like for the Stroke font). Missing to properly acknowledge the license type can get very expensive for you!

UIToolkit for Unity

I am playing around with Unity now for a while now, and  − as probably most of you sooner or later − needed to decide on how to do the good old plain and simple flat 2D UI stuff for menus etc. on top of fancy 3D graphics that you get out of the box with Unity. You can use of course the built-in GUI stuff, but you also probably heard that it’s not such a great idea if your target platform is mobile.

There are tons of frameworks for GUI around, ranging from free to paid, with partially all sorts of add-ons available and the more expensive ones (like NZGUI) probably the way to go if you are really doing high-end development. I, however, stumbled upon UIToolkit by Prime31, and I really found it great for my purposes. It is programmed in an extremely straightforward manner, with easy to understand concepts especially if you are coming from the Cocos2D world. It’s completely free, at the cost of a rather minimal documentation, though.

There is a lively community, but as usual around Unity, it mostly takes place in one endless thread in the Unity forum, and finding things or following a specific topic, or just checking if there are replies at all for a certain question, is not so great. But then, since all the source is available and has a very clean and easy to understand structure, you can almost always find what you need by just checking what happens inside of UIToolkit.

So for some of the solutions to things I wanted to achieve and that I found out either by code reading or by combining bits and pieces I wanted to start a small series of blogs to share those with you. Here you are:

CommentCast Review

FeatureImg

One of the daily routines of developers and publishers is checking the AppStore for the latest ratings and reviews for their products. There are dozens of tools and websites around to support collecting that information, one of which is CommentCast for MAC OS X by Tyler Bindon. And it’s a bit different.

I found CommentCast in search of one tool that also takes ratings seriously. Most tools that I used before had a focus on reviews only. They collected them and notified me, made nice presentations of those new reviews coming up around the world…but they always ignored new ratings being awarded, i.e. reviews without a text, so to say. If you remembered the numbers from the past, you could do the math on your own, but most often you just missed it when new ratings where given somewhere around the world. With CommentCast, this won’t happen again!

Get Started

Selection

You start with selecting the products you want to monitor. This is not just software (iOS & MAC AppStore), but can be any media item from iTunes, like also music, films etc. You can enter a search term, an app ID or AppStore URL and will get a nicely ranked and tagged result list to choose what you want. That result is then added to the list of monitored products, which can be further categorized into subfolders, if you want.

With one click you can now read all worldwide reviews and ratings for a selected or simply all monitored products. When all stores around the world were checked, you get a comprehensive overview about the results in the main window of CommentCast.

Main

With some simple clicks you can now apply filters, e.g. just see values pertaining to the current version  of an app only, filter for number of stars, just show those added after the last poll or simply search within all of the shown. A green badge next to an entry in the app list shows you the number of changes since the last retrieval right away.

ReviewDeltaThe big value over other solutions is that CommentCast also considers simple ratings that don’t come with a review text (usually even the majority of feedback that you get). You get an excellent overview about how many stars you got since the last time you asked for it.

If you simply don’t get what one of your Japanese customers wrote, an integrated translation feature provides a rudimentary translation to a desired target language (Japanese to English translations are a fun entertainment on its own, BTW😉 …)

On the top right of the main screen, a small worldmap indicates the distribution of reviews/ratings around the world. Clicking on it reveals a large view of the map, including an explanation of the color coding.

DistributionMap

Export

CommentCast allows you to export the filtered result list in a configurable HTML format, or simply as a CSV list for export into spreadsheets or other further processing. The HTML configuration is done directly in a template page with some dedicated tags for looping over the content and inserting individual result attributes.

Export

The export has to be done manually, since CommentCast does not yet support Apple script automation. Furthermore, you can not do programmatic filtering or conditional processing within that template, so the usecase for the export is limited. The developer is however looking into extending the functionality in theses areas. I found that feature handy anyway to provide a nice overview of selected reviews to others.

Conclusion

At $5 to be paid through PayPal, CommentCast is a bargain to buy and a must-have for every app developer. The additional consideration of ratings in addition to reviews is an outstanding feature that separates CommentCast from all it’s online and offline competitors. By now I couldn’t live without it any longer and use it at least twice a day! It will get the perfect final touch once the developer adds automation support.

You can download it from the CommentCast homepage.

Café International

The all-time classic board game Café International (Game of the Year 1989!) is finally coming to your iPhone, iPod and iPad. Enjoy an incredibly addictive gameplay, either alone in two challenging solitary modes, or as multiplayer game against friends and computer players. The unique funny original graphics (of course fully supporting iPad retina) and an awesome gameplay and handling will provide a great atmosphere and countless hours of fun and challenges.

Get it right here on the AppStore or watch the product trailer video:

Follow

Get every new post delivered to your Inbox.