[Unity] Prefab里面的Prefab關(guān)聯(lián)問題

最近造了個輪子可以批量替換prefab里的prefab竹挡,歡迎大家測試~https://bitbucket.org/xuanyusong/prefab-replace

最近在做UI部分中遇到了這樣的問題再芋,就是Prefab里面預(yù)制了Prefab独令∠孺遥可是在Unity里面一旦Prefab預(yù)制了Prefab那么內(nèi)部的Prefab就失去關(guān)聯(lián)汰蜘。導(dǎo)致與如果要改內(nèi)部的Prefab需要把所有引用的地方全部改一遍晴弃。今天在逛國外網(wǎng)站看到了一個老外的思路宛瞄,原文在這里http://framebunker.com/blog/poor-mans-nested-prefabs/

下面直接上代碼

using UnityEngine;

#if UNITY_EDITOR

using UnityEditor;

using UnityEditor.Callbacks;

#endif

using System.Collections.Generic;


[ExecuteInEditMode]

public class PrefabInstance : MonoBehaviour

{

public GameObject prefab;


#if UNITY_EDITOR

// Struct of all components. Used for edit-time visualization and gizmo drawing

public struct Thingy {

public Mesh mesh;

public Matrix4x4 matrix;

public List<Material> materials;

}


[System.NonSerializedAttribute] public List<Thingy> things = new List<Thingy> ();


void OnValidate () {

things.Clear();

if (enabled)

Rebuild (prefab, Matrix4x4.identity);

}


void OnEnable () {

things.Clear();

if (enabled)

Rebuild (prefab, Matrix4x4.identity);

}


void Rebuild (GameObject source, Matrix4x4 inMatrix) {

if (!source)

return;


Matrix4x4 baseMat = inMatrix * Matrix4x4.TRS (-source.transform.position, Quaternion.identity, Vector3.one);

foreach (MeshRenderer mr in source.GetComponentsInChildren(typeof (Renderer), true))

{

things.Add(new Thingy () {

mesh = mr.GetComponent<MeshFilter>().sharedMesh,

matrix = baseMat * mr.transform.localToWorldMatrix,

materials = new List<Material> (mr.sharedMaterials)

});

}


foreach (PrefabInstance pi in source.GetComponentsInChildren(typeof (PrefabInstance), true))

{

if (pi.enabled && pi.gameObject.activeSelf)

Rebuild (pi.prefab, baseMat * pi.transform.localToWorldMatrix);

}

}


// Editor-time-only update: Draw the meshes so we can see the objects in the scene view

void Update () {

if (EditorApplication.isPlaying)

return;

Matrix4x4 mat = transform.localToWorldMatrix;

foreach (Thingy t in things)

for (int i = 0; i < t.materials.Count; i++)

Graphics.DrawMesh (t.mesh, mat * t.matrix, t.materials[i], gameObject.layer, null, i);

}


// Picking logic: Since we don't have gizmos.drawmesh, draw a bounding cube around each thingy

void OnDrawGizmos () { DrawGizmos (new Color (0,0,0,0)); }

void OnDrawGizmosSelected () { DrawGizmos (new Color (0,0,1,.2f)); }

void DrawGizmos (Color col) {

if (EditorApplication.isPlaying)

return;

Gizmos.color = col;

Matrix4x4 mat = transform.localToWorldMatrix;

foreach (Thingy t in things)

{

Gizmos.matrix = mat * t.matrix;

Gizmos.DrawCube(t.mesh.bounds.center, t.mesh.bounds.size);

}

}


// Baking stuff: Copy in all the referenced objects into the scene on play or build

[PostProcessScene(-2)]

public static void OnPostprocessScene() {

foreach (PrefabInstance pi in UnityEngine.Object.FindObjectsOfType (typeof (PrefabInstance)))

???? BakeInstance (pi);

}


public static void BakeInstance (PrefabInstance pi) {

if(!pi.prefab || !pi.enabled)

return;

pi.enabled = false;

GameObject go = PrefabUtility.InstantiatePrefab(pi.prefab) as GameObject;

Quaternion rot = go.transform.localRotation;

Vector3 scale = go.transform.localScale;

go.transform.parent = pi.transform;

go.transform.localPosition = Vector3.zero;

go.transform.localScale = scale;

go.transform.localRotation = rot;

pi.prefab = null;

foreach (PrefabInstance childPi in go.GetComponentsInChildren<PrefabInstance>())

BakeInstance (childPi);

}


#endif

}

用法比較簡單,比如我有兩個Prefab爱咬,inside嵌入在Big里面尺借。如下圖所示,把PrefabInstance腳本掛在Big上精拟,然后把inside拖入下方燎斩。


OK 無論怎么修改inside這個Prefab,當(dāng)實例化Big的時候都能得到最新修改的Inside這個Prefab蜂绎。

持續(xù)思考:

界面預(yù)覽問題栅表,就是我在布界面的時候,我需要把子集Prefab界面控件拖進(jìn)來預(yù)覽效果师枣。如果用上述思路UI的Prefab就必須通過腳本自動生成怪瓶。一份是預(yù)覽用的也就是不需要腳本的,一份是只帶腳本運(yùn)行時動態(tài)生成的践美。在處理自動生成UIPrefab的時候可以利用tag 比如像這種需要內(nèi)嵌的Prefab標(biāo)記一個特殊的tag洗贰,在Editor下完成Prefab的導(dǎo)出。另外布界面的時候不需要綁定腳本陨倡,而上述腳本的綁定也應(yīng)該由Editor導(dǎo)出Prefab的時候完成敛滋。

總之一切布界面的時候只操作Prefab不操作腳本。

最近造了個輪子可以批量替換prefab里的prefab兴革,歡迎大家測試~https://bitbucket.org/xuanyusong/prefab-replace

如果有更好的方法歡迎各位朋友在下面給我留言绎晃,謝謝。

本文固定鏈接:?https://www.xuanyusong.com/archives/3042

轉(zhuǎn)載請注明:?雨松MOMO?2014年07月31日?于?雨松MOMO程序研究院?發(fā)表

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杂曲,一起剝皮案震驚了整個濱河市箕昭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌解阅,老刑警劉巖落竹,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異货抄,居然都是意外死亡述召,警方通過查閱死者的電腦和手機(jī)朱转,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來积暖,“玉大人藤为,你說我怎么就攤上這事《嵝蹋” “怎么了缅疟?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長遍愿。 經(jīng)常有香客問我存淫,道長,這世上最難降的妖魔是什么沼填? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任桅咆,我火速辦了婚禮,結(jié)果婚禮上坞笙,老公的妹妹穿的比我還像新娘岩饼。我一直安慰自己,他們只是感情好薛夜,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布籍茧。 她就那樣靜靜地躺著,像睡著了一般梯澜。 火紅的嫁衣襯著肌膚如雪寞冯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天腊徙,我揣著相機(jī)與錄音简十,去河邊找鬼檬某。 笑死撬腾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恢恼。 我是一名探鬼主播民傻,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼场斑!你這毒婦竟也來了漓踢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤漏隐,失蹤者是張志新(化名)和其女友劉穎喧半,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體青责,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡挺据,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年取具,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扁耐。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡暇检,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出婉称,到底是詐尸還是另有隱情块仆,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布王暗,位于F島的核電站悔据,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瘫筐。R本人自食惡果不足惜蜜暑,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望策肝。 院中可真熱鬧肛捍,春花似錦、人聲如沸之众。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棺禾。三九已至缀蹄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間膘婶,已是汗流浹背缺前。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留悬襟,地道東北人衅码。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像脊岳,于是被迫代替她去往敵國和親逝段。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容