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

不羁岁月 提交于 2019-12-11 14:28:07

问题


Assume I have a simple MonoBehaviour

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

I make GameObject, attach a FooScript. 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 someValue.

Assuming I know the path to the prefab how I can make an edit time script that makes edits to the FooScript 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 prefab is null

If switch to

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

prefab is not null but root is

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 PrefabUtility.ReplacePrefab

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.


回答1:


 // this fails
 GameObject prefab = 
    AssetDatabase.LoadAssetAtPath<GameObject>(pathToPrefab));

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

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



回答2:


just cast the loaded object to a GameObject

Object prefab = AssetDatabase.LoadAssetAtPath(pathToPrefab, typeof(GameObject));
GameObject root = prefab as GameObject; //a prefab is also just a gameobject
FooScript = root.GetComponent<FooScript>();
root.someValue = 789;

don't forget to save the changes

EditorUtility.SetDirty(prefab)

AssetDatabase.SaveAssets




回答3:


you need to load a GameObject like this :

 string prefabPath = "Assets/demo1/Resources/GameObject.prefab";
    Object prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);

Don't forget the suffix name



来源:https://stackoverflow.com/questions/38785607/how-to-edit-a-monobehaviours-properties-on-a-prefab-in-the-unityeditor-from-scr

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!