Non-repeating random numbers in Unity

Some folks on the Unity forum were discussing non-repeating random number.  One fast and simple technique for this is known as the Knuth-Fisher-Yates Shuffle. Very useful for randomizing arrays of any type.

 DO THE SHUFFLE!

So I wrote a quick generalized C# template that I use in our code. You can, of course pass in integer arrays, but any other type of array as well. Perhaps, for example, an array of Gamebject prefabs to shuffle the order in which they spawn.

public static void RandomizeArray<T>(T[] array)
{
    int size = array.Length;
    for (int i=0; i < size; i++)
    {
        int indexToSwap = Random.Range(i, size);
        T swapValue = array[i];
        array[i] = array[indexToSwap];
        array[indexToSwap] = swapValue;
    }
}

...to call it with integers...

//
// Non repeating random numbers from 0 to count
// 

int[] indexArray = new int[count];
        
// Fill with sequeential indexes then randomize
for(int i=0; i<indexArray.Length; ++i)
    indexArray[i] = i;
 
RandomizeArray<int>(indexArray);
 
...to call it with game object prefabs...

//
// Non repeating prefab spawn 
//
public GameObject arrayOfPrefabsToSpawn[]; // An array of the prefabs that should be spawned
        
RandomizeArray<GameObject >(arrayOfPrefabsToSpawn);
 
// Now just sequentially instantiate the prefab gameobjects in the arrayOfPrefabsToSpawn as needed.   
// You can, of course, just call RandomizeArray again when the end is reached and start the spawn loop again.
// And, really, for performance, use a spawn pool instead of instantiate!
for(int i=0; i<arrayOfPrefabsToSpawn.Length; ++i)
{
    GameObject.Instatiate(arrayOfPrefabsToSpawn[i]);
    yield return new WaitForSeconds(spawnDelay);
}


Unibill issues with Amazon IAP

I was encountering a fatal error when initializing Unibill on Amazon Kindle. Specifically, it realted to the class "com.amazon.inapp.purchasing.ResponseReceiver" not being found.   I hit it running the latest version of Unibill from the Asset Store, and Unity v4.5.3f3.   

Well, I just figured out that our AndroidManifest in project file had an old Amazon IAP v1.0 receiver path. The path is changed for v2.0. The manifest receive must be "com.amazon.device.iap.ResponseReceiver" - not the path listed above.

Look out for this, anyone carrying a project from Amazon IAP 1.0 to 2.0!

The issue produces a fatal crash and requires console log output to diagnose.

Unity + Amazon GameCircle Implemented on Android

Just finished implementing Amazon GameCircle support in one of Android our titles.   The process was fairly straightforward and fairly well-documented at https://developer.amazon.com/sdk/gamecircle/documentation/unity-gamecircle-setup.html.  

However, there were a few hiccups along the way.  Here were a few key points that hopefully will save someone else time in their implementation:

  1. Don't download the Amazon GameCircle package from the Unity Asset Store.  Because it doesn't work.  Instead, download the latest Amazon SDK zip, extract, and do a Import Custom Asset on the Unity package contained in the archive.
  2. Don't use the short API code the Security profile shows.  Do take the extra step to create the long API key with MD5.  You'll have to extract the MD5 pattern from your apps keystore to generate the API key on the Amazon website, then copy the generated API key from the Amazon developer console.  See https://developer.amazon.com/sdk/gamecircle/documentation/gamecircle-config.html#Section5 for more details.
  3. Make sure the Android app manifest is renamed and correct.  The Android application manifest example file has a lengthy name of "GameCircleExampleApplicationManifest.xml" or something.    Which won't be found.  It'll have to be renamed to AndroidManifest.xml, or else your app's permission settings will be wrong, and you'll be digging out adb logcat to understand why your application stops on a NETWORK_STATE_ACCESS exception or similar.

Good luck!

Continuous Background Music Across Scenes

I noticed a discussion regarding background music continuity across Unity scenes here:

http://answers.unity3d.com/questions/11314/audio-or-music-to-continue-playing-between-scene-c.html?page=1&pageSize=5&sort=votes

Rimrook's solution is a great baseline, but our team wanted a single script solution that could be used on Audio Source objects across scenes.    So I updated the code to allow for new Audio Sources to provide new songs and volume.  

We noticed that, if new Audio Source objects were present with Play On Awake, Unity would start playing the new music on top of the old until the singleton detection finished, creating a brief audio glitch.   So we never set Play on Awake for background music Audio Sources.   The script manages this instead:

using UnityEngine;
using System.Collections;

public class MusicSingleton : MonoBehaviour 
{
    private static MusicSingleton instance = null;

    public static MusicSingleton Instance {
             get { return instance; }
    }

    void Awake() 
    {
        if (instance != null && instance != this) 
        {
            if(instance.audio.clip != audio.clip)
            {
                instance.audio.clip = audio.clip;
                instance.audio.volume = audio.volume;
                instance.audio.Play();
            }

            Destroy(this.gameObject);
            return;
        } 
        instance = this;
        audio.Play ();
        DontDestroyOnLoad(this.gameObject);
    }
}

Workarounds for Unity 4.2+ crashes on Windows 8.1

If you are experiencing crashes or hangs in Unity 4.2 or 4.3 running on Windows 8.1, particularly when importing assets or transferring over an older project, take a look at this:

http://answers.unity3d.com/questions/499583/why-is-my-fresh-unity-42-crashing-on-windows-8.html

We've hit this issue on a couple of systems.   Usually, we can get around the problem by setting the "-force-d3d11" tag on the Unity icon start arguments.   Which seems to work on the desktop icon, but not if you pin to the taskbar, which is annoying.

It is also a good idea to make sure DirectX and graphics drivers are up-to-date, which seemed to help on one of our systems.

Unity Singletons - Life Across Scenes

In finishing out one of our titles, we sought to have uninterrupted music across several loaded scenes.   

The following article on Unity answers has a great Unity singleton model that can be used with objects to create this:

http://answers.unity3d.com/questions/11314/audio-or-music-to-continue-playing-between-scene-c.html

This is also an excellent way to optimize loading for levels that share content.   By creating a singleton container for scene objects, you can ensure that prefabs are loaded only once across scenes.

Rigidbodies on moving platforms

In our 2.5D platformer, we have a large number of rigidbody physics objects, and use rigidbodies for characters, including players.

So, in the spirit of good platform-style games, we added moving "elevator" platforms.   How hard can this be, right?

Bunny rides platform.  Box rides platform.   All is good!

Bunny rides platform.  Box rides platform.   All is good!

Well, tricky enough.   Vertical elevators worked - sort of.  The rigidbodies vibrated on them.   But horizontal elevators  were a fail.  Some rigidbodies would stick and ride, others, well, not so much.  Players and enemies sliding off.

Adding a rigidbody to the elevator made things more odd.  Objects falling through, sinking into the platforms, not the behaviors we were looking for.  

So off to Unity answers!   The most recommended solution was to make the rigidbody become a child transform upon collision in script.   This is a real pain, as we have many different objects that would need this script.  And some character objects ride in other objects, which get tedious.  And we have to tag all the platforms, which makes adds complexity to making cool dynamic elevators in-game.

Then I noticed the solution recommend by HNX at the bottom of the thread below.   PERFECT!  Works great.   Just be sure to make your elevator kinematic and move it in FixedUpdate!

From http://answers.unity3d.com/questions/167404/rigidbody-on-a-platform.html:

Moving using only Rigidbody.MovePosition and Rigidbody.MoveRotation in FixedUpdate fixes the slipping and gives a very smooth and accurate simulation.
From the docs: http://docs.unity3d.com/Documentation/ScriptReference/Rigidbody.MovePosition.html
For kinematic rigidbodies it applies friction based on the motion of the rigidbody. This lets you simulate moving platforms with rigidbodies sitting on top of the elevator. If you want other rigidbodies to interact with the kinematic rigidbody you need to move it in the FixedUpdate function. 

Unity Assets Beyond The Asset Store

Of course, the Unity Asset Store is a phenomenal resource for small studios like ours, but sometimes we needs some obscure piece of art, sound effect, or music that is not in the store.  Recently, I found a great discussion in Unity3D Answers that provides and extensive list of free and paid sites supporting content for Unity.  

Note that a few of the links are dated, but it has been a useful site for our development work.

http://answers.unity3d.com/questions/16650/game-asset-website-list-free-and-paid-textures-mod.html

 

Unity Video Tutorials From Brackeys - Not Bad!

My son is learning Unity, so I wanted to find a video tutorial set focusing on Unity 4, working through at a reasonably slow pace so it would be easy for him to follow.   And I'm sure he gets tired of me talking at him all the time, anyway.  :)

We found a set of Unity 4 video tutorials posted by Brackeys.   They have been pretty good for someone just starting in Unity.  We've gone through the first 7 segments, and it has been pretty good so far.   My biggest gripe is that I would have preferred to see the scripts in C#.   And "TheDammage" :)

Anyway, pretty good starter.  You can find it at: http://www.youtube.com/watch?v=fRED_-LvJKQ

Video below...