PrefabRevolution

原文:http://framebunker.com/blog/poor-mans-nested-prefabs/   (溜还是老外溜啊)

有些时候需要在Prefab里预制一个子prefab,但unity只会默认父prefab,一旦预制了prefab就会与其内部的prefab失去关联;

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

}

PrefabInstance
类能解决这个问题,用法:比如有两个prefab,PrefabFarent和PrefabSon,只需要把PrefabInstance
类挂到PrefabFarent上,把PrefabSon拖到prefab里就行。

这样无论怎么改变PrefabSon,当实例化PrefabFarent时都能得到最新改变了的PrefabSon

父Prefab与子prefab问题的更多相关文章

  1. Unity3D研究院之Prefab里面的Prefab关联问题

    最近在做UI部分中遇到了这样的问题,就是Prefab里面预制了Prefab.可是在Unity里面一旦Prefab预制了Prefab那么内部的Prefab就失去关联.导致与如果要改内部的Prefab需要 ...

  2. JavaScript从父页面获取子页面的值(子页面又如何访问父页面)

    之前还真没做过类似的东西,,top页面获取子页面的document.. 在百度搜了下即找到这个东东,还好,能用. 主要就是使用 contentWindow方法,获取子页面的所有document,再做处 ...

  3. Jquery父页面和子页面的相互操作

    //父页面调用子页面Add函数 $("iframe")[0].contentWindow.Add() //父页面对子页面Id为Sava的Dom元素执行一次单击操作 $(" ...

  4. Caliburn.Micro 关闭父窗体打开子窗体

    比如我们在做登录的时候需要关闭父窗体打开子窗体.使用Caliburn.Micro它的时候我们关闭登录窗口的时候主页面也会关闭. 解决方法就是在登录页面的CS里面写 IndexView iv = new ...

  5. 父容器根据子容器高度自适应:设置父容器 height:100%;overflow:hidden;

    父容器根据子容器高度自适应:设置父容器  height:100%;overflow:hidden;

  6. 父元素与子元素之间的margin-top问题

    父元素的盒子包含一个子元素盒子,给子元素盒子一个垂直外边距margin-top,父元素盒子也会往下走margin-top的值,而子元素和父元素的边距则没有发生变化. html代码: <div c ...

  7. Unity3D研究院之Prefab里面的Prefab关联问题(转)

    转自http://www.xuanyusong.com/archives/3042 最近在做UI部分中遇到了这样的问题,就是Prefab里面预制了Prefab.可是在Unity里面一旦Prefab预制 ...

  8. HTML 父元素与子元素之间的margin-top问题

    问题: 父元素的盒子包含一个子元素盒子,给子元素盒子一个垂直外边距margin-top,父元素盒子也会往下走margin-top的值,而子元素和父元素的边距则没有发生变化. 代码如下: <div ...

  9. artdialog4.1.7 中父页面给子页面传值

    artdialog4.1.7中父页面给子页面传值时看了一些网友的解决方法: 在父页面声明全局变量 var returnValue=“ ”,子页面用art.dialog.opener.returnVal ...

随机推荐

  1. CSS padding margin border属性详解【转载】

    本文转载自:http://www.cnblogs.com/linjiqin/p/3556497.html ,感谢相关博主. 图解CSS padding.margin.border属性 W3C组织建议把 ...

  2. linux awk命令详解【转载】

    本文转载自:http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html 简介 awk是一个强大的文本分析工具,相对于grep的查找 ...

  3. selenium webdriver python 操作浏览器

    新建driver driver=webdriver.Firefox() driver=webdriver.Ie() driver=webdriver.Chrome()   打开一个链接 driver. ...

  4. 【COM学习】之一、QueryInterface

    开始先说一句,学习com之前要学好c++ 对象模型. QueryInterface的使用: QueryInterface是IUnknown的一个成员函数,客户可以通过此函数来查询某个组件是否支持某个特 ...

  5. ulimit开启coredump时核心转储

    [root@localhost ~]# ulimit -c [root@localhost ~]# ulimit -a core data seg size (kbytes, -d) unlimite ...

  6. [置顶] 【SQL】查询重复人名的次数并列出

    select count(姓名) as 重复次数,姓名from 某表 group by 姓名order by 重复次数 asc 首先,group by 姓名,可以将所有相同姓名的项集合在一起.然后,c ...

  7. U1总结

    import java.io.Writer; import java.util.Iterator; import javax.xml.transform.TransformerFactory; imp ...

  8. css元素居中

    水平居中 若为行内元素,对其父元素用text-align:center即可: 若为块元素(无浮动),则一般有两种方法可实现对其的水平居中,一为margin:0 auto;二为通过css计算函数calc ...

  9. 简要介绍 My.Ioc 的用法

    下面这段代码展示了 My.Ioc 的基本用法: using System; using System.Collections.Generic; namespace My.Ioc.Sample { pu ...

  10. (转)jQuery Validate 表单验证

    在做网页表单时时常需要在客户端对表单填写的数据进行验证一番才能提交,我们可以通过自己编写JavasScript代码来验证,但是有时数据量过多时就会有些难度了.基于jQuery的jquery.valid ...