I have a few custom assets that I want to handle is a special way. We recently updated our Unity version from 5.3.4 to Unity 2018, and it looks like there are features for handling this (AssetImporter?), but I’d appreciate some advice.
I have a class that I want to store as a custom asset. Let’s say this class is called StatBlock, and it looks like this
public class StatBlock : ScriptableObject {
public int str; //Strength
public int dex; //Dexterity
public int con; //Constitution
public int int; //Intelligence
public int wis; //Wisdom
public int cha; //Charisma
}
When imported as an asset, I want this to function normally. If I have a MonoBehaviour component with a StatBlock variable on a gameObject in scene, I want to be able to drag the asset directly from the Project pane into the variable slot, etc.
I have this working right now. What I ALSO want, is to be able to directly control how Unity interprets this file. Rather than just serializing this object into binary or text, I’d like to control how Unity imports the associated .asset file into an object, and vice versa. The main reason for wanting this is for backwards compatibility.
For example, let’s say later on in development, I decide Intelligence and Wisdom aren’t different enough, and I merge them into a new stat called Brain. But I have 500, or some other large number, of StatBlocks that will suddenly not have a value for this. Let’s say I decide that the Brain stat for each StatBlock should be equivalent to whichever of Intelligence and Wisdom used to be higher. This is a sort of contrived example, but I assure you this exact case, or something similar, has come up, most commonly with wanting to change how data is stored, or adding additional functionality. Another example might be wanting to store an int array of all six stats, rather than six variables, but wanting the Unity to be able to interpret and create objects out of older files.
I know my way around serialization. If I were able to specify the contents of the .asset file myself, I’d probably put it in json, xml, or csv, and have it store this:
VERSION: 0.1
STRENGTH: 11
DEXTERITY: 11
CONSTITUTION: 11
INTELLIGENCE: 12
WISDOM: 10
CHARISMA: 11
Then, in my hypothetical custom StatBlock importer, I’d have this file generate a StatBlock. If I were using Brain now, I could do something like this
public StatBlock ImportAsset(values v) {
StatBlock sb = new StatBlock();
sb.str = v.STRENGTH;
sb.dex = v.DEXTERITY;
sb.con = v.CONSTITUTION;
sb.bra = Mathf.Max(v.INTELLIGENCE, v.WISDOM);
sb.cha = v.CHARISMA
return sb;
}
, and I could run a switch statement on VERSION to help older assets be imported correctly.
I’d rather that Unity use its normal serialization when it builds the game, so it doesn’t have to deal with my ugly asset formatting. Ideally, when this object gets stored back in the file it came from, it would now store a value for BRAIN and none for INTELLIGENCE or WISDOM. This would involve a custom exporter as well. I can’t figure out the easiest way to implement this. It seems hard to differentiate between when Unity is serializing something to store on disk as an asset file, or serializing it for a build.
Sorry if this is a bit confusing, I’m still trying to figure out the best way to do this. I can clarify anything if needed.