Why Normalize()

I’ve been doing some work on the AI for enemy behaviours for an unreleased game Endless Elevator and have been delving into the book “Unity 2018 Artificial Intelligence Cookbook – Second Edition” by Jorge Palacios.

It uses the Normalize() function regularly to record the direction of an object in relation to another object and it got me thinking about the usefulness of this function.  You can see why something like knowing the direction of the Player could be good for an enemy AI behaviour but I wanted to investigate more deeply about how this worked and how I could use it.

One of the things I hadn’t consciously been aware of, but is obvious once you point it out, is that a Vector3 can define a location (ie. a point in space 0, 0, 0) but it can also define a direction if you have a starting position and a target position.

A good example of a Vector being used to denote a location and a direction in Unity is the Ray.
The Ray consists of two Vector3 data points. The first Vector3 is the source position the ray is taken from and the second Vector3 is the direction of the target.

When a direction Vector3 is Normalized it keeps it’s direction but it’s length (how far away one object is from another) is set to a point between 0 and 1.  In Unity they round down to 0 if the objects are very close to each other (anything under about 0.04f of a unit) anything above that gets Normalized up to 1.

As an example we can simplify a bit by limiting ourselves to a Vector2.

A Vector2 can also be either a point or a direction depending on what you want to use it for.
If it’s (3, 0) then it could be either a point at x=3, y=0, or a direction along the x axis (one dimension) with a length of 3 and a slope of 0.
If you Normalize() that example the Vector2 becomes (1, 0). It will have a length of 1 but still be pointing in the x direction.
If you add the y value (dimension) into the picture where x=3, y=3 the Normalized value becomes (0.7, 0.7). So without going into the maths of why … you can see that the axis/dimensions impact on each other to define the Normalized direction.

We can extrapolate this into three dimensions without too much difficulty but I’m not going to describe that here as it’s not that necessary to understand. We only need to grasp what this means and what sort of use you can make of it in a Unity project.

For Example…

This is a simple use case of why you might want to use Normalize().

(Note that there is also a Normalized() function where the current vector is left unchanged and a new normalized vector is returned).

I’ve created an example project where the relationship between two objects (a Cube and a Sphere) will give us a direction (using Normalize()).  The direction is applied to a transform.Translate function on a third object (a Cylinder) which now moves in the given direction.

In this script below attached to our Green Cube (the unchanging point of origin – 0, 0, 0) we define the Pink Sphere as the target.  In the script we get the difference between the position of the sphere and the Cube and Normalize() it to make a direction. It doesn’t matter how far the Sphere is from the Cube the direction stays the same.

Also to extend the example I’ve added a Ray with the same origin as the Cube (0, 0, 0) that will always point to the Sphere.  This shows that the Normalized Vector3 is the same as the direction of the Ray pointing to the Sphere.

Normalizing Direction

The public Vector3 lineDirection is the difference between the position of the Cube and the Sphere. This is the variable we will pass to the Cylinder to move it in the required direction.

using UnityEngine;
using UnityEngine.UI;

public class HowToNormalizeDirection : MonoBehaviour {

    public Vector3 lineDirection; 
    public GameObject target;   
    public Text vector_text;
    public Text norm_text;
    public Text ray_direction;
    public Ray whatsTheRay;    

    // Use this for initialization
    void Start () {
        lineDirection = new Vector3();
        whatsTheRay = new Ray();
	}
	
	// Update is called once per frame
	void Update () {
        lineDirection = target.transform.position - transform.position;  
        vector_text.text = "Vector3 target.transform.position :" + lineDirection;
        lineDirection.Normalize();  
        norm_text.text = "Vector3 Normalized() :" + lineDirection;
        whatsTheRay = new Ray(transform.position, target.transform.position);
        ray_direction.text = "Ray : " + whatsTheRay.ToString();   
    }
}

Moving the Capsule in the Same Direction

In this script below attached to the Cylinder we get the direction from the lineDirection variable above but we could also have used the inbuilt Ray.direction function to return the same result.

using UnityEngine;

public class MoveCapsule : MonoBehaviour {

    public Vector3 direction;
    public float speed;
    // Use this for initialization
    void Start () {
        direction = Vector3.zero;
        speed = 0.50f;
	}
	
	// Update is called once per frame
	void Update () {
        var script = GameObject.FindWithTag("Cube").GetComponent();   
        direction = script.lineDirection;
        //direction = script.whatsTheRay.direction;  
        transform.Translate(direction * speed * Time.deltaTime); 
	}
} 

In the Video below you can see this demonstrated. The position of the Pink Sphere is being manually manipulated using the Transform on the right. The text areas expose the vector3 values being accessed by the objects and scripts.

So what’s going on in this video amateur hour?

The three lines of text at the top of the game scene represent:

1. The Vector3 Position of the Pink Sphere.

2. The Vector3 Normalized  direction which is the relationship between the position of the Green Cube (0, 0, 0) and the Pink Sphere (x, y, z).

3. The uses of Vector3 in the Ray.  First the position of the origin and then the Direction of the Ray which is exactly analogous to the Normalized Vector3 in point 2 above.

The uses for something like this could extend to a weapon aiming system, a custom controller or be passed into a path finding routine. This is not the only option of course there are other built in methods like transform.LookAt(target) available which may accomplish your programming goal.

During the research for this post I found the following links helpful.

https://docs.unity3d.com/ScriptReference/Vector3.Normalize.html
https://docs.unity3d.com/ScriptReference/Vector3-normalized.html (which is a different but related function)
https://forum.unity.com/threads/what-is-vector3-normalize.164135/
https://answers.unity.com/questions/52881/vector-normalization-question.html
https://www.dummies.com/education/math/calculus/finding-the-unit-vector-of-a-vector/ (for why you really don’t want to know about the math or do it by hand)
https://www.mathsisfun.com/algebra/vector-unit.html (best for simple vector explanation)
https://docs.unity3d.com/ScriptReference/Ray.html
https://docs.unity3d.com/ScriptReference/Ray-ctor.html

Indie Game Release Click Through and Conversion Rates

Hi Harmony here…

Last Sunday we released our game The Dog Run into the Google Play Store.

This post is a breakdown of the first week release click through rates from this web site and the conversion rates that resulted in an actual download of a game.

Let me say from the outset that without some form of “advertising” or publication campaign a new game on the Google Play Store is never going to be successful.  We found this out the first time around with our game NumBlocks:

NumBlocks is a fun little numbers game that’s a bit like Tetris with numbers that add together. It was our first game with Unity and only a bit more than an experiment in finishing a game that looked good enough to publish.  We weren’t that proud of it and were really just proving our development and release cycle for future games.  It was never publicised and never got downloaded…by anyone.  So if you are not promoting your game… no-one is looking … and no-one will play it.

This time around with The Dog Run we really do want people to play the game and enjoy it. The game is a simple endless runner with a quirky hand drawn style that held many interesting development challenges. More information about the game is available here:

The Dog Run

But what I want to investigate and be transparent about is the way we used this web site and the landing page as a way to interest people into playing the game.

We released the game into the Production Google Play Store on Sunday October 21st.

On the next day at about 8 am New York time we posted on social media channels (we found from research, and validated with our own posts over several months on this site, that this is one of the times of the week that got the most traffic).

We only used Reddit, Facebook and Google+ to promote the release of our game.  We Tweeted and posted to LinkedIn and Tumblr but no-one really follows our feeds on those platforms so I won’t count them.

This is the list of Groups that we hit on social:

Facebook

IGC : Indie Game Creators
Unity 3D Game Developers
Unity 3D Game Developers (different group)
UNITY3D Game Developers
GameDev Show and Test
Game Developers
Indie Game Players & Developers!
INDIE GAMES
Indie Game Promo
Indie Game Development Feedback (IGDF)
Indie Game Chat
Indie Game Promotions

Google+

Unity3d Indie game developers
Unity3D Mobile Developers
Unity 3D Enthusiasts
Unity 3D Developers
Android Apps and Games-Android Mobile Zone
Android Game Developer
Free Mobile Games
Game Developers
Game Developers (different group)
Mobile Game & App Developers
Unity
Unity3d Indie game developers
Unity 3D Developers
Unity3D Mobile Developers

Reddit

/r/Games/
/r/gamedev/
/r/androidapps/
/r/AndroidGaming/
/r/gamernews/
/r/IndieGaming/
/r/androiddev/
/r/gamedesign/
/r/devblogs/
/r/SideProject/
/r/playmygame/
/r/Unity2D/
/r/IndieDev/
/r/indiegames/

So what can we say about this set of groups?  Well they are all Gamer’s Groups. These are “our” people. This is where we go when we need feedback or inspiration or help.  We may not be active in all of them and by no means is this an exhaustive list but after working our way through this lot on a Monday morning there is no energy or time left to look for more groups to join and contribute to.  So this is not a “general public” group nor are they representative of what I think our target audience might be.  But these are gaming enthusiasts and I think more likely to try new games and provide that sort of validating critical and informed feedback that is important for making the game better.  (I love you all!)

So now for the stats….

After seven days since posting these are the figures that hit our website (which normally gets about 20 – 30 visitors a day).  The graph below shows the two weeks previous to release and is indicative of the sort of traffic we get. The blue bar just under the 500 mark is what happens when we do a blog post.  The big orange one is the day after our “social media campaign” (if you could call it that).

Total number of visitors over that week was: 1199

But as you can see a day or two after we posted the traffic dropped straight back to normal. Although the traffic we did get that week was all mostly to look at the landing page of the game.

It is interesting to see where that traffic came from  –  and it’s overwhelmingly Reddit that drives the traffic to our site.  This image below is the stats from the big orange day.

So as you can see even though we posted to heaps of groups in Google+ and Facebook not many users of those platforms were reached.

Out of this massive spike in traffic the number of people who actually clicked on the link to go to the Google Play Store was: 76

This is about 6.5% (rounded up) of our total traffic during that period.  Every day during that week the click through rate was about the same average rate.

Now for the fun part.  Out of those 76 players the number who actually downloaded the game and played it was:  21!

Well that’s a huge improvement over none.

I was very excited by this number.  I’ll type it again in long form…..  Twenty One !

So what I want to drive home with this post is the amount of traffic that you got to drive into your web site to get the sort of volumes that will get your game downloaded.

Let’s break it down into simple numbers……  Out of 1200 people only 75 looked at the game and out of that number only 21 downloaded it.  That’s 1.75% of the traffic to my landing page downloaded the game. That’s the truth of it and remember that these are “our peeps” not the general public so I couldn’t even say that this is indicative of the way the real world works.  But it sure is interesting and in a few months after I’ve spent some time marketing this game to real people (not just the gaming community) I’ll do another post and see if the stats still hold.

Harmony out!

P.S. If you want a friendly copy of all those social media links email me at zuluonezero.z10@gmail.com and I’ll forward them back. (Maybe on a later post – if there is enough interest – I’ll  put them online). Zulu.

The Dog Run is in Production on the Google Play Store

This week we moved our latest game The Dog Run into Production on the Google Play Store.

The Dog Run is an Endless Runner for Android that supports animal welfare!

It’s a free game. There is the option to watch ads but instead of in game rewards all profits from the advertising goes to support animal welfare and animal hospitals.

The game is about taking your fun lovin’ pooch for a run. But watch out! There is a bunch of obstacles in your path. It’s a good thing your dog is a natural jumper and can run all day in all sorts of weather.

Read the review from Daikon Media here.

They say, “… it’s not only the style, that I like, it’s also the unique sense of humor…the game is even fun and original.”

Feedback can be posted on the Google Play Store,  on this website in the comments,  or directly by email.

ZuluOneZero Game Design
http://www.zuluonezero.net/
zuluonezero.z10@gmail.com

Image File Size in Unity and their Impact on Start Up Time on Android

Xander here…

We have been Beta Testing our soon to be released game The Dog Run and it’s been mostly OK but we had a number of issues with memory on smaller or older devices.  We made some gains with modifying our audio files (See this post) but were still running into niggling crashes on start up and longer than normal load times.

We were getting feedback like:

“Hey, I installed the game and couldn’t run it. When I started it there was a black screen for about 15s and then it went back to the launcher. Then each time I went back to the game there was unity and game logo fading out and again the app crashed/hanged and I was sent back to the launcher.”

(Thanks slomoian and the_blanker for all your help testing)

Obviously feedback like this is a little disheartening and far from ideal.  The game was running fine on every device and emulator I had access to but it’s only when you send something into the wild that you realise the full breadth of the spectrum that is the Android platform.  I guess this is another lesson in the importance of proper Beta testing.  One we hadn’t learned last time we released an app (see this old post on the perils and difficulty of finding Beta Testers).

We were using adb logcat to monitor our start up problems but not finding a “smoking gun” that solved every case. It seemed to be a memory problem and often with the graphics cache so again we went back to the Unity Editor build log to investigate our image files.  The game uses multiple large files to ensure that our animated sprites were always in the right spot. The game is dependent on the titular Dog hitting the ground line accurately on every frame to achieve the look we wanted when he runs and the paw breaks the ground line and appears as a gap.  We used a “flip-book” old fashioned style of animation where each frame sits exactly on top of the old frame and everything lines up on a transparency like in classic animated movies.

By using this schema we had to keep to a certain scale that fit within the constraints of a typical Android device format. This meant that when the images were imported the POT was not going to be something we could play with easily to get performance gains.  (Image files that have a width and breadth that is a power of 2 are faster and easier for the compression functions to work with – so 2, 4, 8, 16, 32, 64, 128, etc).  If I had the chance to do this again this is something I would probably start doing right from the beginning of development. When going through the Editor Logs we did find something interesting (get to the Editor Logs by right clicking on the arrow or tab near the Console and selecting it).

We found that some of our image files were 10 MB and a few were 2 MB.  Which was a little weird as they were all exported as layers from the same Gimp file so I must have done something in the import settings or the editor to change them.

This is a comparison of two files of the same dimensions and basically the same content but with two very different file sizes:

10.6 mb 0.8% Assets/artwork/RunOnSpot6.png

2.0 mb 0.1% Assets/artwork/DogSitHeadWag.png

The difference that I found was MIP Maps.  I’d selected to use MIP Maps fairly early on as it made the art work look smoother in the Editor.  MIP Maps are generated in the engine to make smaller more compressed versions of your artwork that can be used at longer distances from the camera where the detail is less visible. My game is 2D and has everything running at pretty much the same distance from the screen so really MIP Maps should not be required.  My art did look a bit better in the editor with them turned on but on a smaller device like a phone I couldn’t really tell the difference.  See below the difference in a file with MIP Maps selected and a file without.

With MIP Maps turned on (see the file size at the bottom and that the type is RGBA 32 bit):

The same file with MIP Maps removed (down to 2 MB and using ECT2 compression):

This is the difference that generating those MIP Maps makes. Your file is converted from the Android default compression to a larger (harder to process) 32 bit compression format.

So by turning off MIP Maps across the three hundred plus image files in my game reduced my application start up time to under a few seconds and reduced the APK file size by over one thousand MB.

This is the Build Report from the Editor Logs that shows the larger texture sizes and final build size:

Uncompressed usage by category:
Textures 1292.3 mb 94.6%

Complete size 1365.9 mb 100.0%

Compare this later Build Report with MIP Maps turn off to the original one above:

Textures 284.5 mb 82.6%

Complete size 344.6 mb 100.0%

It’s a considerable difference with little or no quality loss on most devices.  When I say most devices there were a few cases where the running dog did look a little tatty.  On very small emulated devices (3.5″ screens and low memory) the images were being scaled down quite a lot and the results were a lot less enjoyable but still an acceptable compromise considering previously the game would not run on these devices at all.

The next thing I started playing with was the different texture compression variables available for Android. I tried all of the settings (see screenshot below) in a different build and tested them against at least ten different devices with various architectures and screen dimensions and Android versions.

In each of the cases but one there was at least one test device that failed to start the game.  Once again exposing the issues of working with so many platform variables on Android.  Even when I built the APK with the (default) ETC selected one device failed the start up test.  So in the end the final build used the “Don’t override” setting which seemed to work on all devices.

Hopefully this is helpful to someone else out there and if it is try hitting the “Like” button below or sharing the link (the feedback keeps me going).

I found these references useful when troubleshooting my start up issues and learning more about compression on Android:

https://docs.unity3d.com/Manual/android-GettingStarted.html

https://docs.unity3d.com/Manual/class-TextureImporterAndroid.html

https://docs.unity3d.com/Manual/class-PlayerSettingsAndroid.html

https://answers.unity.com/questions/1406451/sprites-increase-android-apk-size.html

https://www.unity3dtips.com/unity-texture-compression-android-ios/

Making the Audio for our Promotional Video

Hi The Baron here…

This post is about the making of the soundtrack to the promotional video for our game in beta testing: The Dog Run.

The “Promo Video” is used in the Google Play Store to show potential players of the game what it’s like and to induce them to download it.  The request from the Zulu head was to make some “EPIC!” music that took off the more elaborate over the top games out there that looked way more exiting than they actually were in their videos. Since our game was really very simple in concept and delivery we thought it would be funny.

First off with all creative endeavours I had a good afternoon nap and while I was under the somnambulists influence I started thinking about how I wanted to start working on this EPIC! if short piece. I decided on an orchestral theme and came up with a rhythmic loop that I thought I could develop into a larger piece.

I started with the piano and a four on the floor click track to get down the basic concept. Admittedly it sounds a little thin, and hardly epic, but it had the right qualities that I thought might grab a listener given enough scale.

 

I bumped up the concept with some doubling with the orchestral patch in the Korg M1 (one my favourites for wide sounding strings and general orchestra stabs).  I also added a faint backbeat to keep it moving. It starts to sound a bit better.

 

Next to get that EPIC! feel of drama and driving action I added an arpeggiated violin track. I know the playing is a little loose but it get’s tweaked up later on and adds a little spontaneity that is lost when you use an automated device.

 

So it’s starting to get there and I keep building on it.  I add some duplicated lines for the orchestral and rhythmic patterns I already have by doubling up the strings and adding two more lines of violin with slightly different sounds or accented playing. I also beef up the percussion with orchestral kettle drums and other tuned deep rhythm instruments. Now it sounds a little bit EPIC.

 

This is what it looks like in the Editor (I’m using Reason 10).

 

Finally to throw us over the top I added the leading kettle drum roll and the harmonic vox choir to lift us up.  I kinda like it now so I start adding a very limited effect chain (mostly some reverb) and add compression and filtering on some parts – here is the final EPIC! cut.

If you like it “Like” it or send us a comment if you are feeling really verbose.