Search Unity

Creating prefabs from models by script

Discussion in 'Prefabs' started by Cobo3, Jan 3, 2019.

  1. Cobo3

    Cobo3

    Joined:
    Jun 16, 2013
    Posts:
    67
    Hi,

    Before updating to Unity 2018.3, we used to have a custom AssetImporter for model types. Doing so, upon importing a new model in the project we could create a prefab for that model. If the prefab already existed, we replaced it.

    Now, with the Nested Prefabs workflow, I am unable to use the new API.

    Code (CSharp):
    1. if( !File.Exists( destinationPath ))
    2.     return PrefabUtility.CreatePrefab(destinationPath, modelAsset);
    3. else
    4.     return PrefabUtility.ReplacePrefab(modelAsset, AssetDatabase.LoadAssetAtPath<GameObject>(destinationPath), ReplacePrefabOptions.ReplaceNameBased);
    Now I am supposed to call SaveAsPrefabAsset instead, as far as I know, in both situations. When I do so, however, I get an ArgumentException saying "Can't save persistent object as a Prefab asset".

    What should I do to be able to create a prefab from a model by script?
     
    Airmouse likes this.
  2. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    639
    Hi,

    That does sound like a bug, could you file a bug report please.

    That said I strongly recommend you explore using Prefab Variants if you want to have Prefabs based on Models.
    Using Variants means that changes to your models propagate automatically and you don't have to manually update your custom Prefabs.
     
  3. Cobo3

    Cobo3

    Joined:
    Jun 16, 2013
    Posts:
    67
    If that's indeed a bug, I will report it.

    About prefab variants, it sounds great to make a prefab variant from the model, but how can I do that from code?
     
  4. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    639
    Variants are basically instances of other prefabs saved into their own separate prefabs.
    So instantiate the model and save the instance to a new prefab.

    Code (CSharp):
    1. var modelRootGO = (GameObject)AssetDatabase.LoadMainAssetAtPath("Assets/MyModel.fbx");
    2.  
    3. var instanceRoot = PrefabUtility.InstantiatePrefab(modelRootGo);
    4. var variantRoot = PrefabUtility.SaveAsPrefabAsset(instanceRoot, "Assets/MyModel_Variant.prefab");
     
  5. Cobo3

    Cobo3

    Joined:
    Jun 16, 2013
    Posts:
    67
    Instantiating the model, creating a prefab from the instance and then destroying the instance solved the problem.

    Thank you so much!

    I still sent a bug report though.
     
  6. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    Now that ReplacePrefab w/ ReplacePrefabOptions.ReplaceNameBased is obsolete what is the alternative?

    With ReplacePrefab w/ ReplacePrefabOptions.ReplaceNameBased I create Prefabs with a script (I have 100's of prefabs with identical & complex hierarchies) and this allowed me to adjust & modify prefabs without breaking all scene instance serialized links. Now that ReplacePrefab w/ ReplacePrefabOptions.ReplaceNameBased is obsolete I am unsure what to do. I just used PrefabUtility.SaveAsPrefabAsset and it broke my scene serialized links (I lost a LOT of work!).

    Edit: Looks like this will be fixed. Unity post here.
    https://forum.unity.com/threads/alternative-to-replaceprefab.607759/#post-4114699
     
    Last edited: Jan 22, 2019
    Mistermind and golmae like this.
  7. Totoro83y

    Totoro83y

    Joined:
    Sep 21, 2013
    Posts:
    21
    If this is a bug is a very unfortunate one. I have to load an fbx GameObject to extract a child object and make a prefab of it.

    I can't load it with PrefabUtility.LoadPrefabContents because is an fbx and not a normal prefab.

    I can't always create a new temporary scene for something that seems a regression of this:
    https://issuetracker.unity3d.com/is...-models-configure-menu-in-inspector-is-opened
    and this problem is very common if you try to reimport an fbx because you probably select it when reimport it.

    I can't save directly the fbx to alter it after this because of this bug.

    The only way I see to create my prefab is to instantiate it in the current scene and then remove it, but this alter the scene I'm working...
     
  8. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    According to this thread Unity stated...

    "We’re working on a replacement for ReplacePrefab. You can keep using the obsolete API in the mean time. The replacement was meant to have been done when we shipped but didn't make it. It's a mistake on our part that the old method was marked obsolete without the replacement being ready. Sorry for the inconvenience."

    https://forum.unity.com/threads/how...scripts-w-the-new-system.613747/#post-4113010
     
  9. Totoro83y

    Totoro83y

    Joined:
    Sep 21, 2013
    Posts:
    21
    Yep, I know, but even with ReplacePrefab I got the error "Can't save persistent object as a Prefab asset", so that doesn't change a lot.
     
  10. Elviro

    Elviro

    Joined:
    Feb 26, 2019
    Posts:
    1
    Hello everyone, I am trying to save a gameobject as a prefab in edit mode, but the prefab is being saved with its MeshFilter but not the actual mesh. Is there a way I can save the prefab and keep the reference to the mesh?
     

    Attached Files:

    Jinja likes this.