Unity3D研究院之Prefab里面的Prefab关联问题
最近在做UI部分中遇到了这样的问题,就是Prefab里面预制了Prefab。可是在Unity里面一旦Prefab预制了Prefab那么内部的Prefab就失去关联。导致与如果要改内部的Prefab需要把所有引用的地方全部改一遍。今天在逛国外网站看到了一个老外的思路,原文在这里 http://framebunker.com/blog/poor-mans-nested-prefabs/
下面直接上代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
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,当实例化Big的时候都能得到最新修改的Inside这个Prefab。
持续思考:
界面预览问题,就是我在布界面的时候,我需要把子集Prefab界面控件拖进来预览效果。如果用上述思路UI的Prefab就必须通过脚本自动生成。一份是预览用的也就是不需要脚本的,一份是只带脚本运行时动态生成的。在处理自动生成UIPrefab的时候可以利用tag 比如像这种需要内嵌的Prefab标记一个特殊的tag,在Editor下完成Prefab的导出。另外布界面的时候不需要绑定脚本,而上述脚本的绑定也应该由Editor导出Prefab的时候完成。
总之一切布界面的时候只操作Prefab不操作脚本。
如果有更好的方法欢迎各位朋友在下面给我留言,谢谢。
Unity3D研究院之Prefab里面的Prefab关联问题的更多相关文章
- Unity3D研究之Prefab里面的Prefab关联问题
Unity研究院之Prefab和GameObject的正向和逆向查找引用 我发现很多美工兄弟都爱问程序Unity3d为什么总丢材质? 我不排除U3d有BUG的情况下会丢材质?但是其实很多时候是人为操作 ...
- Unity3D研究院之Prefab里面的Prefab关联问题(转)
转自http://www.xuanyusong.com/archives/3042 最近在做UI部分中遇到了这样的问题,就是Prefab里面预制了Prefab.可是在Unity里面一旦Prefab预制 ...
- Unity3D研究院编辑器之不实例化Prefab获取删除更新组件(十五)
http://www.xuanyusong.com/archives/3727 感谢楼下的牛逼回复更正一下,我表示我也是才知道.. 其实不需要实例化也能查找,你依然直接用GetComponentsIn ...
- jmeter压测学习3-提取json数据里面的token参数关联
前言 现在很多接口的登录是返回一个json数据,token值在返回的json里面,在jmeter里面也可以直接提取json里面的值. 上一个接口返回的token作为下个接口的入参. 案例场景 我现在有 ...
- UMG里没有"Prefab"怎么办?
大家知道在Unity里做UI,利用Prefab是少不了的,但是在UE4里如何做呢? 这是实际工作中遇到的问题,我Google关键词“UMG Prefab","UMG resuabl ...
- (转)Unity3D研究院之Assetbundle的原理(六十一)
Assetbundle 是Unity Pro提供提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbundle中,提供了封装与解包的方法使用起来很便利. 1.预设 A ...
- (转)MoMo的Unity3D研究院之Assetbundle的原理(六十一)
http://www.xuanyusong.com/archives/2373 Assetbundle 是Unity Pro提供提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbun ...
- Unity3D研究院之Assetbundle的原理(六十一)
www.xuanyusong.com/archives/2373 Assetbundle 是Unity Pro提供提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbundle中,提供 ...
- Unity3D研究院之Jenkins的使用(七十八)
长夜漫漫无心睡眠,来一篇嘿嘿.我相信如果已经用Shell脚本完成IOS和Android打包的朋友一定需要Jenkins 怎么才能让策划打包ipa和apk?怎么才能彻底省去程序的时间,只要在同一局域网内 ...
随机推荐
- python基础04 运算
数学运算 print 2+2 #加法 print 1.3-4 #剪法 print 3*5 #乘法 print 4.5/1.5 #除法 print 3**2 #乘方 print 10%3 #求 ...
- python基础01 Hello World!
摘要:简单的Hello Word! python 命令行 如已经安装python,那么在linux命令行中输入 $python 将进入python.乱吼在命令行提示符>>>后面输入 ...
- Python调用HTTP接口并传递cookie
#get接口调用 import urllib import urllib2 get_url = "http://10.10.3.63/test?id=123&name=nba&quo ...
- warning C4996: 'sprintf': This function or variable may be unsafe
选项Project | Configuration Properties | C/C++ | Preprocessor | Preprocessor Defin ...
- js~~给网站图片添加水印~~~
因为朋友问我怎么加水印,引起了我的兴趣,没接触过也没想过要怎么写,所以试了试.写了一个简单的demo......
- Java序列化、反序列化和单例模式
学习JAVA的时候,特别是涉及到网络编程时,我们时常让我们的实体类实现一个接口 public class Entity implements Serializable{ } 这样子我们可以通过输入输出 ...
- dictionary 应用(绑定dgv)
dictionary的用法://初始化添加所有车位进这队列 Utility.Effectlist.Add(); //每触发一次,用这个增加数量 Utility.Effectlist["Car ...
- CSS样式,雪碧,图片替换,渐变小析
Css基础2: 相对长度单位:em,rem,px,%绝对长度单位:厘米等(不用)颜色单位:rgb,rgb的百分比,16进制(#),颜色名称字体:font-size:为了更好适合点阵,尽量使用偶数fon ...
- 输入/输出系统的四种不同工作方式对CPU利用率比较
程序控制工作方式:输入/输出完全由CPU控制,整个I/O过程中CPU必须等待其完成,因此对CPU的能力限制很大,利用率较低 程序中断工作方式:CPU不再定期查询I/O系统状态,而是当需要I/O处理时再 ...
- 深入理解Spark(一):Spark核心概念RDD
RDD全称叫做弹性分布式数据集(Resilient Distributed Datasets),它是一种分布式的内存抽象,表示一个只读的记录分区的集合,它只能通过其他RDD转换而创建,为此,RDD支持 ...