Trying to create a prefab from an instantiated object from an AssetBundle.

Hi, I am trying to create a Prefab from a GameObject that I load and instantiate from an AssetBundle. I am doing this all in Edit Mode within the same project. When I instantiate the object, I can inspect it and see all of my scripts and everything is working as expected, however when I then turn this into a prefab I get errors about the fileID of my scripts being invalid.

Object myAsset = bundle.LoadAsset("MyAsset");
GameObject instance = GameObject.Instantiate(myAsset);
PrefabUtility.SaveAsPrefabAsset(instance, "Assets/MyAsset.prefab");

Broken text PPtr. GUID 00000000000000000000000000000000 fileID 6656884677904845236 is invalid!

When I inspect the prefab that does get created all of my custom scripts are missing.

I have also extracted the AssetBundle using WebExtract and binary2text, I can see my scripts have the correct class, namespace and assembly.

It seems that these fileID’s do not get updated to what is in the project and instead are still using what is in the AssetBundle, but I am only guessing here. Any idea how to work around this?

I am not sure if this makes a difference but I should say the AssetBundle in question was created by the Addressables package; but from what I understand this is using the standard AssetBundle code under the hood.

Lastly, I am using Unity 2020.3.6f1.

Thanks.

I am getting closer but I feel Unity has a bug somewhere around this. I am experimenting around trying to find a way for Unity to re-link the source of my components with what is in the project, the following code gets me close but is not a proper solution. For one it will not copy materials (for some reason) and the second is this would not properly retain object/component references to be within the cloned object. I am adding it here in the hopes it could spark some ideas.

Object myAsset = bundle.LoadAsset("MyAsset");
GameObject instance = GameObject.Instantiate(myAsset);
GameObject clone = CloneObject(instance);
PrefabUtility.SaveAsPrefabAsset(clone, "Assets/MyAsset.prefab");

public static GameObject CloneObject(GameObject source)
{
    if (source == null) return null;

    GameObject dest = new GameObject();
    EditorUtility.CopySerialized(source, dest);
    dest.name = dest.name + "(copy)";

    for (int i = 0; i < source.transform.childCount; i++)
    {
        GameObject child = CloneObject(source.transform.GetChild(i).gameObject);
        child.transform.SetParent(dest.transform);
    }

    Component[] coms = source.GetComponents<Component>();
    foreach (Component srcCom in coms)
    {
        Component destCom = dest.GetComponent(srcCom.GetType());
        if (destCom == null)
        {
            destCom = dest.AddComponent(srcCom.GetType());
        }

        EditorUtility.CopySerialized(srcCom, destCom);
    }

    return dest;
}

The prefab in this case still shows some fileID invalid and could not extract GUID errors but upon inspection all my components are there.

Thanks.

I created this script.
Feel free to use it.

7579420–939352–AssetBundleExtractor.cs (11.6 KB)