Unity: Simple state-save for pick-up objects in games
Sunday, December 14th, 2008Now that I’m working with Unity full-time, I’m having a lot of fun learning the system, and it’s pros and cons. I’m still unsure of the best strategy to do big save-games, but I’m not too worried about that for my first game. But I want to make save/load data easy to use when building levels.
Unity’s PlayerPrefs allows you to save and load data using name/value pairs. It’s pretty general and reminds me of Director’s SetPrefs (Did Tom help them design this feature?
). One thing I have not been able to figure out though, is how to get a unique ID for a gameObject that I can turn into a name for PlayerPrefs. Let me walk you through an example:
You have a health pickup prefab, and it’s name is “HealthPrefab”. These prefabs are scattered throughout the level. When you pick them up, you want them to stay picked up, even if you leave the level and come back. This can be done with playerPrefs, but because you have multiple instances of the health prefab in the level, you need a unique name for each one.
This could be done by assigning a name to every instance of the prefab using the inspector, but this is time-consuming for the designer, and error-prone.
It can’t be done with GetInstanceID because while this number is unique per object, it changes every time you load the level.
The best solution I have come up with so far is to generate a unique name based on the position of the object in the scene. Here’s how I do it:
Object name + Scene name + Transform x + y + z
With this code, you can add prefabs to your level at your leisure without having to name them uniquely, and they’ll just work.
I actually use integers of X Y and Z to make the name shorter, and this just means you have to make sure your pickups are at least 1 unit away from each other. For most games this should not be a problem, but if it is, just modify the name-generator to use higher-res values. In my game, the name-generator is a static function that every object calls, but in my script here I stuck it in the same script. I’d love to know what people think of this, and if anyone knows of a better way to do this, let me know!
// Simple Pickup code -- .js -- for Unity
private var savename = "";
function Start ()
{
savename = savename(this.gameObject, "pickup"); // Generate a Unique Savename.
if (PlayerPrefs.GetInt(savename,1) == 0 )
{Destroy(this.gameObject); }
}
function OnTriggerEnter (hitby : Collider)
{
{// Put some code here to check to see if the item that triggered you can pick you up
PlayerPrefs.SetInt(savename, 0);
Destroy(this.gameObject);
// do some "you picked me up!" sound effects, etc
}
static function savename (object : GameObject, ilabel : String)
{ // Call this to get your unique save name!
// this builds a unique savename by stringing together the object's level name, X, Y, and Z locs (interegers of), and a prefix that is defined
// by the object itself. The idea is that this is a uniqueish enough key for saving the status of an in-game object.
// Ideally this function is a master function somewhere, rather than in every type of pick-up script you have.
return ilabel + "." + Application.loadedLevelName + "." + parseInt(object.transform.position.x) + "." + parseInt(object.transform.position.y) + "." + parseInt(object.transform.position.z); // this makes a unique name for this object. Kinda.
}


[see all of my
So far Unity looks pretty cool. It’s apparent that it is optimized for making games compared to Director (which takes a more general approach). That is, there’s a lot of primitives and built-in game-oriented options that don’t require scripting, or even using pre-written scripts. That’s a breath of fresh air compared to Director, which pretty much requires you write your own systems for just about everything. The way the editor interacts with scripts reminds me a lot of Leia, which was LucasArt’s in-house level editor originally written for Jedi Knight (which I did level design for).

I'm Hanford Lemoore. My parking skills are unparalleled.





