2016-08-05 54 views
1
在UnityEditor一個MonoBehaviour的屬性

假設我有一個簡單MonoBehaviour如何在預製從腳本編輯

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

我做遊戲物體,附加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 

但使用的是因爲我不得不想盡一切遊戲物體和或FooScript哈克的解決方案。我的意思是我想作爲一個實用的解決方案,它可能會工作,但它感覺像增加技術債務,我將不得不稍後修復

我試過的其他事情是創建一個新的遊戲對象和新的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 

但這不適合我。預製件中的值被替換,但場景中的所有實例都斷開連接。

重申。我不想編輯預製的實例。我試圖在編輯時從腳本編輯預製件本身。

+0

你通過HTTPS嘗試:/ /docs.unity3d.com/ScriptReference/AssetDatabase.html? – 2016-08-05 09:33:17

+0

是的,對不起。 「資產」是一個錯字。更新了這個問題 – gman

+0

[here](http://forum.unity3d.com/threads/assetdatabase-loadassetatpath-not-working.134913/),他們建議使用[Resources.LoadAssetAtPath](https://docs.unity3d.com /ScriptReference/Resources.LoadAssetAtPath.html),但文檔說這是depricated – ColmanJ

回答

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; 
+0

你的理由在第二個解決方案對我來說沒有意義。對象只是基類的一個例子。沒有什麼變化。 – gman

+0

我認爲是因爲'Object prefab = AssetDatabase.LoadAssetAtPath (prefabPath);''''PrefabUtility.ReplacePrefab'將被調用'null'失敗。但是,預製件不會被替換,所以它確實沒有完全意義。仍然高興有一個解決方案通過溝通不暢然後:) – ColmanJ

+0

哦,是的,我應該嘗試再次使用替換。不完全確定這是我想要的,但我會試一試。 [見新問題](http://stackoverflow.com/questions/38787298/how-to-update-a-prefab-property-from-editor-script-and-have-the-instances-get-th):P也許答案是要取代預製?雖然這實際上很糟糕,因爲我必須將舊的預製件的所有屬性複製到新的屬性中,然後修改我的一個字段。嗯:( – gman

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

+0

這是我第一次嘗試。 '所以沒有預製不是一個gameobject :( – gman

+0

@ gman你使用'AssetDatabase'類嗎?因爲在你的示例代碼中它說'Ass et'。那麼'root'的價值是什麼,因爲如果這也是'null',那麼你的路徑可能是錯誤的。 – ColmanJ

+0

是的,我使用了'AssetDatabase'。對不起,'Asset.'是一個錯字。還有,以防萬一不是我低估了你的答案。我更新了這個問題。 – gman