How to check if a GameObject loaded from an AssetBundle is a PREFAB ?

I am loading my gameobjects from AssetBundle, but it loads objects with identical names.

AppleItem.prefab
AppleItem.dae

Both will be loaded as a GameObject named “AppleItem”.

How can I check if a GameObject is a prefab or not?

AssetBundle theBundle = AssetBundle.LoadFromFile(AssetBundlePath + bundleName);
GameObject[] allPrefabs = theBundle.LoadAllAssets<GameObject>();
foreach (GameObject prefab in allPrefabs)
{
     //Check if GameObject is a Prefab or a different file (.dae)
}

According to this Unity Answer by masterton, it isn’t possible. Is the only way to do this to have all my prefabs with a naming prefix? “prefab_AppleItem.prefab”, “Collider_AppleItem.dae”? Or doing one of the hacky solutions in that Answer? (Not sure I trust that old info). This seems so silly…not to mention annoying since I’d have to refractor my code & rename hundreds of prefabs (a.k.a. write a script to mass rename files).

There has GOT to be a simpler way. Is this not a part of the Unity API? Prefabs are the epitome of Unity development.

Far as I can tell, asset bundles don’t like stuff to be named the same thing. It’s been 2 years since we started using them and I just went the route of not naming stuff in the same asset bundle the same thing and never worried about it after that.

Which in a way, sort of makes sense if you consider you could have two images named the same for example, just coming from different folders.

I think my original attempts way back I had a prefab and an image named the same, but couldn’t get them to work together.

That is unfortunate. At the very least, we could have access to the file extension name (.prefab, .dae, .png, etc.) It is so dumb that Unity hides this.

I decided instead of painfully renaming all of my files, it would be better to simply have two sets of asset bundles: One for “Assets” and one exclusively for “Prefabs”. The latter will be dependent on the former, but that isn’t a problem since I load all asset bundles at the beginning from local disk. As long as you load the _assets Bundle first, you can then just work with your _prefabs Bundle as you need without messing with its dependencies. Instantiating a Prefab from the _prefabs bundle will automatically load its dependent _assets into memory for you.

Here is my code to preload certain assets from disk, if anyone finds this thread.

using System.Collections.Generic;
using UnityEngine;
public class CustomAssetBundleManager : MonoBehaviour
{
    public static Dictionary<string, AssetBundle> allGlobalAssetBundles = new Dictionary<string, AssetBundle>(); //AssetBundles for things that will ALWAYS need to be loaded. Player, GUI, items, etc.
    public static Dictionary<string, AssetBundle> allLocalAssetBundles = new Dictionary<string, AssetBundle>(); //AssetBundles that will need to be loaded & unloaded based on what location/level the player is currently in.
    public static string AssetBundlePath; //The path to the AssetBundles
    public static AssetBundle allScenesBundle;

 void Start ()
    {
        AssetBundlePath = Application.streamingAssetsPath + "/AssetBundles/";
/*You should have all your AssetBundles which come with the game download in the StreamingAssets folder.
Unity's AssetBundleBrowser allows you to build for both AssetBundleManager's Simulation
(above Assets folder, in your project's root directory)
AND copied to StreamingAssets folder for builds.
Be sure to checkmark "Copy to StreamingAssets" in the "Build" tab of the AssetBundleBrowser
And DO NOT build assetbundles with AssetBundleManager. Use the AssetBundleBrowser.*/

        DontDestroyOnLoad(gameObject); //Dont Destroy on Load if you ever need to Load/Unload bundles again.
 
       //If you have any vital bundles, like Scene, which need to be loaded.
       allScenesBundle = AssetBundle.LoadFromFile(AssetBundlePath + "AllScenes");

        //Load all AssetBundleManifests. The assets don't load into memory when you load the bundles, so I see no reason not to load all bundles on disk, immediately at the start.
        LoadAllGlobalAssetBundleManifests();
        LoadAllLocalAssetBundleManifests();
    }
    void LoadAllGlobalAssetBundleManifests()
    {
        //Here you type the actual bundle names, and whether or not it should be stored globally (almost always loaded) or locally (loaded/unloaded consistently)
        LoadAssetBundleManifest("global_core", true); //A very important bundle with a few very specific objects

        LoadAssetBundleManifest("global_items_assets", true); //Content - Textures, Animations, Colliders, etc.
        LoadAssetBundleManifest("global_items_prefabs", true); //Prefabs Only

        LoadAssetBundleManifest("global_player_assets", true);
        LoadAssetBundleManifest("global_player_prefabs", true);

        LoadAssetBundleManifest("global_foliage_assets", true);
        LoadAssetBundleManifest("global_foliage_prefabs", true);

    }
    void LoadAllLocalAssetBundleManifests()
    {
        LoadAssetBundleManifest("Level1_npc_assets", false);
        LoadAssetBundleManifest("Level1_npc_prefabs", false);

        LoadAssetBundleManifest("Level2_npc_assets", false);
        LoadAssetBundleManifest("Level2_npc_prefabs", false);

        LoadAssetBundleManifest("Location1_environment_assets", false);
        LoadAssetBundleManifest("Location1_environment_prefabs", false);
    }

    //This function is what ACTUALLY loads the AssetBundle. You could have it return an AssetBundle, or add to a reference List/Dictionary.
    void LoadAssetBundleManifest(string bundleName, bool isGlobal)
    {
        AssetBundle theBundle = AssetBundle.LoadFromFile(AssetBundlePath + bundleName);
        if (isGlobal)
        {
            allGlobalAssetBundles.Add(bundleName, theBundle);
        }
        else
        {
            allLocalAssetBundles.Add(bundleName, theBundle);
        }
    }
}

Then once the game starts, you load the globals assets into memory, or you load/unload local assets.

   private void LoadToMemory_AllGlobalObjectPrefabs()
    {
        foreach (AssetBundle theBundle in CustomAssetBundleManager.allGlobalAssetBundles.Values)
        {
            if (theBundle.name.Contains("prefabs"))
            {
                GameObject[] allPrefabs = theBundle.LoadAllAssets<GameObject>();
                foreach (GameObject prefab in allPrefabs)
                {
                    AllObjectPrefabsInMemory.Add(prefab.name, prefab);
                }
            }
        }
    }