gman gman - 2 months ago 9x
C# Question

How to edit a MonoBehaviour's properties on a prefab in the UnityEditor from Script

Assume I have a simple


public class FooScript : MonoBehaviour {
public int someValue = 0;

I make GameObject, attach a
. I make a prefab from that and delete in instance in the scene.

In the editor I can select the prefab in the project and I can edit

Assuming I know the path to the prefab how I can make an edit time script that makes edits to the
instance inside the prefab?

What've tried

GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(pathToPrefab);
GameObject root = ???? // WHAT DO I CALL HERE!?
FooScript fooScript = root.GetComponent<FooScript>();
fooScript.someValue = 789;

Actually in that case
is null

If switch to

Object prefab = AssetDatabase.LoadMainAssetAtPath(prefabPath);
GameObject root = prefab as GameObject;

is not null but

Next I tried this

Object[] objs = AssetDatabase.LoadAllAssetsAtPath(prefabPath);
foreach (var o in obs)
Debug.Log(" type:" + (o.GetType().Name));

That prints

type: GameObject
type: Transform
type: FooScript

But using that is a hacky solution as I'd have to try every GameObject and or FooScript. I means I suppose as a pragmatic solution it might work but it feels like adding technical debt I'll have to fix later

Other things I've tried is creating a new prefab with a new GameObject and a new FooScript and calling

GameObject newGameObject = new GameObject();
FooScript fooScript = newGameObject.AddComponent<FooScript>();
fooScript.someValue = 789;

Object prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
PrefabUtility.ReplacePrefab(newGameObject, prefab, ReplacePrefabOptions.ConnectToPrefab);

GameObject.Destory(newGameObject); // don't want this in the scene

But that's not working for me. The values in the prefab get replaced but all instances in the scene get disconnected.

To reiterate. I'm NOT trying to edit an instance of a prefab. I'm trying to edit the prefab itself from a script at edit time.

 // this fails
 GameObject prefab = 

 // this fails
 GameObject prefab = 
    AssetDatabase.LoadAssetAtPath(pathToPrefab, typeof(GameObject));  

 // this succeeds
 GameObject prefab = 
    AssetDatabase.LoadAssetAtPath(pathToPrefab, typeof(Object)) as GameObject;