如何在脚本中编辑UnityEditor中的预制件上的MonoBehaviour属性

时间:2016-08-05 09:16:35

标签: c# unity3d

假设我有一个简单的MonoBehaviour

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

我制作GameObject,附上FooScript。我从那里制作一个预制件并在场景中删除。

在编辑器中,我可以选择项目中的预制件,然后我可以编辑someValue

假设我知道预制件的路径如何制作编辑时脚本,以便对预制件内的FooScript实例进行编辑?

尝试了什么

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

实际上在这种情况下prefab为空

如果切换到

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

prefab不为空,root

接下来我尝试了这个

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

打印

type: GameObject
type: Transform
type: FooScript

但是使用它是一个hacky解决方案,因为我必须尝试每个GameObject和/或FooScript。我的意思是,我认为这是一个实用的解决方案,它可能会起作用,但感觉就像增加技术债务,我将不得不在以后修复

我尝试过的其他事情是使用新的GameObject和新的FooScript创建一个新的预制件并调用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

但那不适合我。预制件中的值会被替换,但场景中的所有实例都会断开连接。

重申一下。我不是要编辑预制件的实例。我正在尝试在编辑时从脚本编辑预制件本身。

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

将加载的对象转换为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;
不要忘记保存更改

EditorUtility.SetDirty(prefab)

AssetDatabase.SaveAssets

答案 2 :(得分:0)

您需要像这样加载GameObject:

make

别忘了后缀名