C# Resources.LoadAll Problem

Im trying to dynamically load certain object at runtime into a HashTable. The problem is LoadAll load all the objects twice, i hacked around that by checking if they kay value already exists but for some reason it still adds the object. Here is the code:

	void LoadAllPlants()
	{
		Object[] pPlants = Resources.LoadAll("Plants");	
		
		foreach( Object pObj in pPlants )
		{
			if( !m_ShopItems.ContainsKey( pObj.name ) )
				m_ShopItems.Add( pObj, pObj.name );
				
			Debug.Log( pObj.name );
		}
		
		Debug.Log( m_ShopItems.Count );
	}

There is definitely only one prefab in this folder, i even created a separate folder to test this and the same thing happened. The logs display the exact same name and the count is always 2. Is there a bug here?

This happens on Unity iPhone 1.7 on the Editor and on device.

Your Add call is backwards: m_ShopItems.Add( pObj.name, pObj );
Key first then value.

Ahhh. Thanks for that. Any clue why LoadAll returns duplicates?

with corrected Add it won’t dublicate anymore as the same key can’t be inserted twice
above code itself does not load stuff 2x so I would guess you call the function twice at the time

Its only called the once by its Awake function:

        void Awake()
	{
		m_ShopItems = new Hashtable();
		LoadAllPlants();
	}

Iterating this block of code reveals two of each object: Object[ ] pPlants = Resources.LoadAll(“Plants”);

I modified the code to this as a quick test:

        void LoadAllPlants()
	{
		Object[] pPlants = Resources.LoadAll("Plants");	
		
		foreach( Object pObj in pPlants )
		{
			Debug.Log( pObj.name );
		}
	}

Even with a duplicate function call the output would not appear like it does (see attachment)

In the plants subfolder there are 3 types and they are logged consecutively. Im sure i’ve used this before and not had this problem.

The problem is resolved anyways so thanks to you both. But i would like to know if this is a bug.

dreamora, HashTable Add will throw an exception if the key already exists. As we established, the problem was that FluidPixel_Gavin was using an object for the key (thus unique keys for two different objects).

I don’t know if it’s a bug. What’s the type of object returned? This frustrates me that it’s type “object”; is this because Unity automagically converts them to whatever resource they are? (bitmaps turned into textures, wav files turned into audio objects, etc?)

The return is always UnityEngine.Object until you cast it because it can’t return a mixed array, there is no such thing in .NET or compiled languages. UnityEngine.Object is the base class so the most natural class to use.

Nothing with automagics or alike.

And the error in Add does not explain why he got it inserted twice into the hashtable unless the function itself is called twice :slight_smile:

The objects are prefabs of GameObjects. They are successfully cast into GameObjects for use without crashing. I never question how Unity does its stuff, its magical sometimes, especially the web player, that thing is genius. I think it returns Object because everything inherits from it and will allow safe casting to the appropriate type.

Oi, that’s what I’m trying to say. Unity is creating multiple different types of objects through Resources.LoadAll rather than a single common type with common properties (such as ResourceName, ResourceType) which you can then use to access the data (akin to System.IO.FileInfo). I’d rather it use a common wrapper type (I’m a stickler for type-safety and tend to hate “object”)

Secondly, dreamora, as I said, it was inserting twice into his hashtable because he was providing unique keys for the duplicate objects (he was passing the object hashcode, which is unique, instead of the string name, which was shared) I doubt the method was being called twice.

FluidPixel, can you log out:
Object[ ] pPlants = Resources.LoadAll(“Plants”);
Debug.Log("Resources List Size: " + pPlants.Length);

Ahhh, i thought you were asking a question. I didnt think it might create the Object type and a GameObject type. Is there any way to Log a classes type?

.GetType() gives you a representation of its type, which has loads of useful tidbits: Type Class (System) | Microsoft Learn

Object[] pPlants = Resources.LoadAll("Plants"); 

foreach(Object plantObj in pPlants)
{
	Debug.Log("TYPE: " + plantObj.GetType().FullName);
}

Success.

It adds a Transform and a GameObject type. Am i creating prefabs wrong somehow? Im gonna have to look into prefabs to see why its doing this.

I don’t know, I guess Unity considers that for each prefab you made there it has two resources for it? I haven’t really worked with prefabs much so I can’t speculate beyond that.

At anyrate, you can use the overload “LoadAll (path : string, type : Type)” to filter the types:

Object[ ] pPlants = Resources.LoadAll(“Plants”, typeof(GameObject));

And this really grinds my gears, why isn’t this generic? Then it could be type-safe like this:
GameObject[ ] pPlants = Resources.LoadAll(“Plants”);

You cant use Generics on the iPhone anyways. I had some grand plan for dictionaries but they were smashed to pieces when i realised. I should have used the typeof in the first place.

Thanks for all your help. There shall be a plant in this game named after you.

Don’t do that, I’m anti-vegtite.

Ballllls, iphone splurf

Anti vegtite?

Not even google knows what that means. Please enlighten me :slight_smile:

I’m kidding, I’m just saying I’m against vegetation, so don’t name a plant after me.

Thats totally wrong.
Since U3 its actually not possible to get 1.1 target at all anymore as such you couldn’t cut generics at least on the C# side even if you wanted to

I dont have the luxury. My boss refuses to upgrade all our copies to 3 :frowning: No retina display for me.

I should have said its impossible for me but i was not aware its now possible in Unity 3. I want it even more now.