Search Unity

How to add a component to a prefab?

Discussion in 'Prefabs' started by hjupter, Dec 18, 2018.

  1. hjupter

    hjupter

    Joined:
    Dec 23, 2011
    Posts:
    621
    Hi, I've read the docs already and I've been trying to AddComponent to a prefab so I know that I have to load content first then modify then save it and unload but I cannot this to work I'm not really sure what I'm doing wrong. Help!!?!!

    This is the code:
    Code (CSharp):
    1. if (PrefabUtility.GetPrefabAssetType(this.instance.gameObject) == PrefabAssetType.Regular)
    2.             {
    3.                 string path = AssetDatabase.GetAssetPath(this.instance.gameObject);
    4.                 var go = PrefabUtility.LoadPrefabContents(path);
    5.                 go.AddComponent(actionType);
    6.                 EditorUtility.SetDirty(go);
    7.                 PrefabUtility.SaveAsPrefabAsset(go, path);
    8.                 PrefabUtility.UnloadPrefabContents(go);
    9.             }
     
  2. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    436
    What exactly does
    this.instance.gameObject
    reference?
    Are you getting any failures?
     
  3. hjupter

    hjupter

    Joined:
    Dec 23, 2011
    Posts:
    621
    yes this.instance.gameObject its just a reference to gameObject or prefab.

    Before I was getting this error
    Code (CSharp):
    1. Assertion failed on expression: '!go.TestHideFlag(Object::kNotEditable)'
    that's why I started changing the code add a component.
     
  4. hjupter

    hjupter

    Joined:
    Dec 23, 2011
    Posts:
    621
    Anyone?
     
  5. fdb_look_soft

    fdb_look_soft

    Joined:
    Dec 13, 2015
    Posts:
    7
    Hi, im getting these errors too hjupter, did you find a way to workaround it yet ?

    Need help to adapt the code workflow bellow :(

    Code (CSharp):
    1.  
    2.    Object prefab = PrefabUtility.CreateEmptyPrefab (scenesPath + "Prefabs/" + gob.name + ".prefab");
    3.    PrefabUtility.ReplacePrefab (gob, prefab, ReplacePrefabOptions.Default);
    4.    PrefabUtility.DisconnectPrefabInstance (gob);
    5.    GameObject.DestroyImmediate (gob);
    6.    Resources.UnloadAsset (prefab);
     
  6. hjupter

    hjupter

    Joined:
    Dec 23, 2011
    Posts:
    621
    I couldn't find a solution so I had to roll back to 2018.2.. I'm still waiting for an answer :(
     
  7. fdb_look_soft

    fdb_look_soft

    Joined:
    Dec 13, 2015
    Posts:
    7
    ahh ok :(. Im testing the use of PrefabUtility.LoadPrefabContents(..) in my code different workflows (I endup modifying the prefab instead of an instance of it lol ) im still at it hehe. we wait I guess.
     
  8. OldLegWig

    OldLegWig

    Joined:
    Mar 18, 2018
    Posts:
    66
    I've been running into the same issue and from what I gather it is the intended behavior, not a bug. It seems like the new features of variants and nesting etc. come with a trade off of flexibility at runtime.

    It seems to me like losing the ability to programmatically make prefab variants (adding/removing components) and instances at runtime is a heavy price to pay. Am I just not understanding some other way to do this sort of thing without having to modify the original prefab?
     
  9. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    436
    @hjupter

    Are you getting any errors from the script?

    I have attached a very simply project that works as expected.

    Simply open the SampleScene and select the Prefab instance and notice it has no RigidBody.
    Now select the prefab in the project browser and select the menu item
    Prefabs/Add RigidBody
    .

    Now notice that the instance has a RigidBody and all new instances of the prefab will have a rigidbody.
     

    Attached Files:

    Last edited: Jan 2, 2019
    hjupter likes this.
  10. hjupter

    hjupter

    Joined:
    Dec 23, 2011
    Posts:
    621
    Thanks @SteenLund your demo works as expected, my problem might be that doing this
    Code (CSharp):
    1. if (PrefabUtility.GetPrefabAssetType(this.instance.gameObject) == PrefabAssetType.Regular)
    instead of
    Code (CSharp):
    1. if (PrefabUtility.IsPartOfPrefabAsset(go))
    I will give it a try later today and will let you know. I appreciate your help!