Showing posts with label UI.. Show all posts
Showing posts with label UI.. Show all posts

Monday, November 21, 2016

Updates!

Hey all, just wanted to give you an update.

I won that contest that I mentioned earlier for the ultra small computer case.  I was on edge for a while there, because some of the other entries looked really good.  But while they all looked good, I don't think they would have been functional without a LOT more engineering work done on them. Anyway, here's what it looked like finished. Had a lot of fun putting this together, and big thanks to Ed who requested the contest for choosing me as the winner.

I have another update as well.  As I type, I'm uploading another version of Cubix Rube to the google play store.  Once updated you'll find an improved rubix cube experience, with more intuitive face selecting, pinch to zoom functionality, as well as a short solving tutorial thanks to how-to-solve-a-rubix-cube.com.

If you like rubix cubes, please check it out, have a download, and let me know what you think via reviews or comments on this blog.  I'll talk to you guys later.

Monday, September 21, 2015

Lag Spikes! How I hate Thee!

So, throughout the last week of testing Eruptoid on my mobile device, I noticed a rather consistent lag spike every second or so.  Being somewhat noobish when it comes to troubleshooting such things, I took a few wild shots in the dark to try and fix it.

Game's lagging?  Must be my visual effects from my particle generators.  Let me turn those down... no change?  Too many polygons?  I only have about 2000 triangles, so that can't be it.  Let me pull up the profiler.  The unity profiler basically provides a frame by frame glimpse at every function call your game is executing, and just how long, in milliseconds, it takes for that function call to execute.  Through some trial and error in figuring out how to get the profiler to talk to my phone while the phone was playing the game, I finally got a picture of what was going on.  Sure enough, every second you could see a spike in the profile graph.  We'll just pause the profile and examine one of the spikes.

Remember that blog post I had a couple of weeks ago about how awesome Unity's new GUI system was?  How I no longer had to manually calculate the size of fonts to get them to be legible on screen?  I take a good chunk of my enthusiasm for that back, because it is the dynamic font scaling that is causing my game to lag.

Here's how it works (according to my understanding).  You have a font which needs to be scaled by whatever factor it needs scaling by to match your target screen resolution.  Unity does this at runtime.  But it doesn't just do a one time calculation for what font size it needs.  Instead, it scales the font one letter/number at a time, and then writes that font at its correct size out to a texure.  Then, when unity needs to display that same character at that same size, it just references the texture instead of calculating the font all over again.  But textures are of fixed sizes, and chances are that the texture will eventually get filled up with all the different font data.  When that happens, unity creates another texture, twice the size of the first, copies everything from the first texture into this new texture, deletes the old texture, and then continues on filling up the new texture with new scaled font characters.  This can repeat numerous times, every time the texture gets full.

I imagine this isn't usually a problem, except that I have a real time countdown clock which is updating every frame, creating a different scaled texture every frame, and thus filling the font texture very quickly.  The function "Font.CacheFontForText" ends up getting called once or twice a second, and every time it does my framerate dips, momentarily, very low.  Why you end up with is a stuttering experience, where things are smooth as butter, and then hitch, and then smooth again.  Its very distracting and very annoying.

Even more annoying was the suggestions for fixing it.  "Don't use dynamic fonts".  Seriously.  The whole point of the new unity GUI was to make a user interface easily scale-able to any resolution without a lot of manual calculations.  On fonts, this is done by making them dynamic.  So the solution to the problem is to not use the new unity gui.

Unacceptable.

But I had an idea for a work around.  It might not be perfect, and probably won't work on low end devices (sorry guys, optimizations come later).  I still use the dynamic font, but I limit the framerate to 1/2 the refresh rate of the devices screen.  On most mobile's, that means 30 fps.  When I limit it this low, the amount of font changes that need caching drops, and the lag spikes all but disappear.

Its not ideal.  Its a workaround, not a fix.  And until Unity fixes the lag spikes on Android caused by Font.CacheFontForText, its the best I'll be able to do.

Monday, September 14, 2015

OnGUI and the new UnityUI system

I'm going to fast forward a bit on this blog to the present day, or at least work I was doing today.  I mentioned before that I started Eruptoid back in the Unity 4.3 days.  Back in those days there wasn't a simple, easy to use, user friendly GUI design system.  Buttons were all created in code with an OnGUI function call.  Button and text positions were all determined in code, and called out sizes in pixels.  This is fine if you're programming for a single target resolution, but as soon as the idea of changing screen sizes enters the equation, all bets are off.  This was especially frustrating when programming for Android, since android devices at the time had screen sizes that ranged from 800x480 to 1920x1080.  So programming a button in the bottom right of a screen 800x480 would require completely different code than one at 1920x1080.  This forced me (and I imagine, everyone else) to do some major workarounds, or purchase 3rd party gui addons such as UGUI.  Here's an example of creating a button in the top middle of the screen that would reload the title screen:

if (GUI.Button (new Rect(Screen.width/2 - Screen.width/10, Screen.height/10,Screen.width / 5, Screen.height / 10), "Back to Title")){
Application.LoadLevel("Title_Screen");
}



Yep.  For each and every gui element I wanted to show on the screen, I had to do a relative position and size calculation manually.  It was tedious, slow, and obnoxious.  Plus, creating a style synergy between your GUI and the rest of your games aesthetic was a process I still don't understand.  So you end up with a pretty plain looking button.

Fast forward to today.  In Unity 4.6, they released a new feature called Unity UI.  It created a graphical user interface for the developer to implement a graphical user interface in their games.  Ground breaking stuff, I know.  It has a ton of features that were handled previously in an arcane style system known as a GUI skin.  Now each individual gui element can have its own style, and the workflow matches much of the rest of the Unity object oriented workflow.  Just drag and drop elements as needed into the inspector and the design area.

It uses a game object called a "canvas" to paint and position the UI onto.  The canvas can be relative to camera space, world space, or screen space.  And best of all, the Unity UI almost painlessly scales your UI elements flawlessly to any resolution.

I say almost painlessly, because there are still some things that feel like need a bit more work.  Text fields on buttons, for example, have an option to scale to fit, but don't have a very good way to constrain what area to scale inside of.  Obviously, text fits inside the button, but buttons can have different outlines/styles, and sometimes the text would end up overflowing outside the graphic for the button with certain styles.  I'm still trying to figure out all the nuance, but its a vastly improved system over the old.

Which brings me to today.  Today I spent most of the afternoon creating new borders for my panels and buttons, and the recreating my old OnGUI buttons and text fields into the new UnityUI version.  It makes things look way more polished than with the stock buttons.  To finish the example, here's a similar button now that does the same thing.

That border and background?  I made that using Blender.  It was a pretty simple process that I'll go into in a different blog post.  But here's a teaser screen shot.



I created a 3D lighted version of the border, and then rendered a 2D texture from it.  Blender is awesome.  Seriously.  If you have any interest in doing anything with art, from texturing to 3D modeling, to video editing and compositing, Blender is what you want to learn.

Blender blender blender blender.  Blender blender.  Blender Blender Blend.  Time for bed.