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. Wii硬盘游戏管理

    简介 wuyou是我心目中的Wii硬盘游戏管理神器,没有之一. wuyou不仅仅是一个游戏管理软件,它最亮点的地方在于集成了“游戏文件格式的转换功能”,电玩巴士上如是说: 用Wii主机来把游戏复制到硬 ...

  2. 2013=12=2 bitree-----补充

  3. 在vim下写python 会出现python错误:unexpected unident

    需要在.vimrc  的set tabstop=4的这一行上面增加  set expandtab 否则会报unexpected unident

  4. libvirt hypervisors信息采集

    libvirt采集hypervisors信息的通用格式 driver[+transport]://[username@][hostname][:port]/[path][?extraparameter ...

  5. sqlserver2012的审计功能的相关理解

    1.sqlserver2012可以做实例的审计,以及数据库的审计,基本包括了所有的操作.可以符合我们的要求.   2.审计功能需要实例级别的配置数据库级别的配置,实例上建立“审核”,数据库上建立“数据 ...

  6. 使用jquery生成二维码

    二维码已经渗透到生活中的方方面面,不管到哪,我们都可以用扫一扫解决大多数问题.二狗为了准备应对以后项目中会出现的二维码任务,就上网了解了如何使用jquery.qrcode生成二维码.方法简单粗暴,[] ...

  7. javascript 判断是否是数组

    function isArray(object){ return object && typeof object==='object' && typeof object ...

  8. Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON

    I create a very simple website.when I run website from VS2012 ,website easily can get data from SQLS ...

  9. Jenkins+maven+git+sonar 系统持续集成&amp;代码单測管理

    Jenkins+maven+git+sonar 系统持续集成&代码单測管理 Jenkins的安装 Jenkins是基于Java开发的一种持续集成工具,用于监控持续反复的工作.功能包含: 1.持 ...

  10. java 中读取本地文件中字符

    java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...