Fun with Generics, arrays and other somnipathy

Ok, I’m trying to automagically find all the objects in a given scene that implement my ISaveable interface, so that I can do some time based and event based persistence. However… the d*mned FindObjectsOfType seems to be causing me trouble (this is happening in Unity v3.0.0 fyi), here’s the line with errors (according to the editor):

List thingsToAutoSave = new List (FindObjectsOfType (ISaveable) as ISaveable[ ]);

The errors read:
Assets/iPhone Standard Assets/Scripts/PersistenceManager.cs(12,76): error CS0119: Expression denotes a type', where a variable’, value' or method group’ was expected

Assets/iPhone Standard Assets/Scripts/PersistenceManager.cs(12,57): error CS1502: The best overloaded method match for `UnityEngine.Object.FindObjectsOfType(System.Type)’ has some invalid arguments

Assets/iPhone Standard Assets/Scripts/PersistenceManager.cs(12,57): error CS1503: Argument #1' cannot convert object’ expression to type `System.Type’

Anyone?

Thanks in advance,

Galen

I think you need to have typeof(ISavable) for FindObjectsOfType.

You may also find this useful if you keep having problems with FindOfType:

ISaveable.cs

public static List<ISaveable> saveables;

void Start() {
  // init
  saveables.Add( this );
}

(My C#'s a little rusty, so that might need a correction or two)

You can then, instead of “findobjectsoftype”, just use “ISaveable.saveables” as the array to save.

You’ll also have to implement a way to remove destroyed objects from the list, but that shouldn’t be too horribly difficult.

Also, I’m going to be using the word “somnipath” or some variant of it every day for the next week. <3

That did it!

Thanks!

The intent of the code is auto detection of elements that need to be periodically saved without needing to manually manage arrays of gameobjects/scripts. With my implementation, any class that implements the interface will be auto-detected at start time and checked periodically to see if it has updates (for the timed method, the event model will be real time), then the information that the class wants saved/tracked will be persisted. Right now I’m using PlayerPrefs, but I can switch that at any time to a database or flatfile, xml, whatever.

Oh, and somnipathy is what I tell people my job is :slight_smile: also applies to my hobbies, but who’s counting :slight_smile:

Just a word of caution: FindObjectsOfType is a very expensive operation. It becomes increasingly expensive when the number of run-time objects increases. Just a single FindObjectsOfType call can cause a noticable framedrop when your scenes grow larger.

Agreed, I only use Find variants in Awake, and sometimes Start… I have used the old “set up arrays in the Editor” method up until lately, but I’m getting tired of reworking every array for common functionality, so I’m working towards “auto-harvest” arrays and object references, so as to be able to drop them into a scene and they just work. I don’t like the “dontdestroyonload” approach, mostly because it’s like placing static classes/variables everywhere… yes it works, but it never gets cleaned up (also doesn’t work if the variables actually change each level/scene.

What do you use?

Galen

We usually use FindGameObjectsWithTag, followed by a GetComponent<>. It is a lot faster, but definitately more restricted (it only works on Components, you need to make sure to tag your objects and you cannot have multiple tags on a single GameObject).

For certain situations, a subscribe/unsubscribe mechanism in OnEnable/OnDisable can also work well.