Unity3D for iOS: “Exception: can’t find texture details for texture packer sprite” w/ UIToolkit’s UI.firstToolkit.addSprite()

Had another run in with the Exception error today while using the open source UIToolkit library.

I have a UI object with three UIToolkit child objects attached in the Hierarchy – two for separate Fonts and one for buttons & other graphics. I tried adding a basic image as a Sprite like so and got the error:

var bgSprite = UI.firstToolkit.addSprite( "mainMenuBg2x.png", 0, 0 ); 

//Null Reference error.... 
/*
Exception: can't find texture details for texture packer sprite:mainMenuBg2x.png
UISpriteManager.addSprite (System.String name, Int32 xPos, Int32 yPos, Int32 depth, Boolean gameObjectOriginInCenter) (at Assets/Plugins/UIToolkit/BaseElements/UISpriteManager.cs:342)
UISpriteManager.addSprite (System.String name, Int32 xPos, Int32 yPos) (at Assets/Plugins/UIToolkit/BaseElements/UISpriteManager.cs:327)
mainMenuScript+$animateIn$27+$.MoveNext () (at Assets/Scripts/MyScript.js:85)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
mainMenuScript:Start() (at Assets/Scripts/MyScript.js:67)
*/

The first step to figure this out was to see what “UI.firstToolkit” is actually pointing to. When I ran this following Debug line, I saw that it was referring to “UIToolkit – text2”, the 3rd UIToolkit child object in UI, according to the Hierarchy layout. :

Debug.Log("UI.firstToolkit = " + UI.firstToolkit); 

//Results in Console window: 
/*
UI.firstToolkit = UIToolkit - text2 (UIToolkit)
UnityEngine.Debug:Log(Object)
$:MoveNext() (at Assets/Scripts/MyScript.js:83)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
mainMenuScript:Start() (at Assets/Scripts/MyScript.js:67)
*/

Sure enough, that wasn’t the correct UIToolkit object. The one I needed is called “UIToolkit – buttons” and in the Hierarchy it was located as the first child of UI.

I took a look at the UI.cs class that came with UIToolkit and saw that it contained a private reference to the collection (array) that holds all of the UIToolkit child objects under the UI object. I also saw that the “firstChild” was a “static public var”. As a quick workaround for my issue, I created another static public var for the entire array and it worked.

Plugins/UIToolkit/UI.cs

...
public class UI : MonoBehaviour
{
	// All access should go through instance and you are trusted not to set it 🙂
	static public UI instance = null;
	static public UIToolkit firstToolkit = null; // we stick the first available toolkit so when using one atlas the API remains simple
	static public UIToolkit[] myToolkitInstances = null; 
...

      private Awake() {
      ...
		// grab all our child UIToolkits
		_toolkitInstances = GetComponentsInChildren<UIToolkit>();
		firstToolkit = _toolkitInstances[0];

		myToolkitInstances = _toolkitInstances;
      ...
      }

	// Ensures that the instance is destroyed when the game is stopped
	protected void OnApplicationQuit()
	{
		instance = null;
		firstToolkit = null;
		myToolkitInstances = null;
	}
	
	
	protected void OnDestroy()
	{
		instance = null;
		firstToolkit = null;
		myToolkitInstances = null;
	}
...
}

Then, I simply used “UI.myToolkitInstances[2]” like so to access the specific UIToolkit child I needed:

var bgSprite = UI.myToolkitInstances[2].addSprite( "mainMenuBg2x.png", 0, 0 );

This is a hack that helped me move forward – not necessarily the best thing to do.

Advertisements