I posted about this in a related post yesterday, but I think the more general question deserves a topic in this forum (Unity UI as a subforum really doesn’t suit this problem).
What I’d like to find out, is if it is possible to have store a reference to an asset (by fileID/guid/type, like .unity files do), and then when the game is being compiled, update this reference to correctly point to the compiled asset at runtime.
Note that the reference is being serialized to a file (in StreamingAssets), and NOT being stored on a MonoBehaviour (where this already happens). The specific use-case I have is pointing to a sprite from a ScriptableWizard that stores the GUID in a class to StreamingAssets. When loading that file at runtime, the Sprite needs to be assignable from that reference somehow.
This is possible in the Editor through the AssetDatabase, but no such database exists at runtime that I know of.
I’m going to see if I can find ways to work around this issue, but if anybody has any other ideas/information, that would be very helpful.
Here’s the topic I posted to earlier: Serializing Sprites? - Unity Engine - Unity Discussions
Here’s the best workaround I could come up with:
I started looking for the place where what I need to happen (updating references) happens always, regardless of if something is in a scene: the Resources folder.
My workaround is to create a prefab from the ScriptableWizard, containing a MonoBehaviour with the data that I wish to store. Then in order to load this info, I simply load that prefab again and extract the data.
This is the relevant code I’m using to do this:
public static class ItemDatabase
{
static List<ItemData> items = new List<ItemData>();
public static List<ItemData> Items
{
get
{
return items;
}
}
static ItemDatabase()
{
Object o = Resources.Load ( "itemdata" );
if ( o != null )
{
GameObject g = GameObject.Instantiate( o ) as GameObject;
items = g.GetComponent<ItemDataContainer>().data;
#if UNITY_EDITOR
GameObject.DestroyImmediate( g );
#else
GameObject.Destroy( g );
#endif
}
}
static void Save()
{
#if UNITY_EDITOR
Object prefab = PrefabUtility.CreateEmptyPrefab("Assets/Resources/itemdata.prefab");
GameObject g = new GameObject("ItemData", typeof(ItemDataContainer));
g.GetComponent<ItemDataContainer>().data = items;
PrefabUtility.ReplacePrefab( g, prefab );
GameObject.DestroyImmediate( g );
#endif
}
}
public class ItemDataContainer : MonoBehaviour
{
public List<ItemData> data;
}
[System.Serializable]
public class ItemData
{
public UnityEngine.Sprite sprite;
//bunch of other data…
}
Tried it in a standalone build and it appears to work. It’s completely agnostic as to where a sprite is stored in your project or what atlas it is in. I’m probably going to have it automatically add them to an item atlas if it isn’t already atlassed.