NestedPreb
屌丝手动版
One of the things we’re sorely missing from Unity is nested prefabs. So we rolled this little script to help us out – and figured other people could benefit as well.
You just add this script to a gameobject, and point the prefab field at the prefab you want instantiated.
This will render the prefab in the scene view while editing, and at bake time it will copy the objects into the scene so your gamecode can just work. It doesn’t allow overriding properties, and only previews the meshes, but we’ve been able to use it a lot for building props: We have a Gameobject that contains all the logic for a prop (e.g. definitions of cover points for a crate) – and then uses this script to pull in the actual FBX file that has the graphics. Now our graphic artist can just modify that and everything works.
You can also reference other prefabs, and nest these PrefabInstance scripts. While not as cool as a real system, it pretty much has solved our use cases.
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 = ; 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 (,,,)); }
void OnDrawGizmosSelected () { DrawGizmos (new Color (,,,.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(-)]
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
}
It uses the same principle as our IBakeable interface, but we want this to run before all the other IBakeable functions (so all objects are instantiated before we try to run others)


NestedPreb的更多相关文章
随机推荐
- jsp获取绝对路径----${pageContext.request.contextPath}
JSP取得绝对路径 在JavaWeb开发中,常使用绝对路径的方式来引入JavaScript和CSS文件,这样可以避免因为目录变动导致引入文件找不到的情况,常用的做法如下: 一.使用${pageCont ...
- Leetcode 137.只出现一次的数字II
只出现一次的数字II 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? ...
- 全文索引(A-1)-用户数据收集(用户研究)
推荐系统根据用户的信息和历史行为记录,构造出用户的个性化模型,再依据特定的推荐算法,向用户推荐其可能感兴趣的项目. 如何获取用户的偏好? 建议用户对一些指定项目进行评分,如对:小说.传记.技术书.图画 ...
- 593. Valid Square
Problem statement: Given the coordinates of four points in 2D space, return whether the four points ...
- topshelf生成Windows服务
一. 概述 Visual C# 工程中选取 Windows 服务(Windows Service)选项,可以创建Windows服务程序,这种开发方式对于开发来说不方便调试,今天介绍另外一种生成Win ...
- 【NOIP2016】蚯蚓(单调队列)
题意: 思路: 我们发现,对于任意两次切割i和j,i<j,在进行完第j次切割后,第i次切割的u/v部分一定大于等于第j次切割的u/v部分,第i次的1-u/v部分也一定大于等于第j次的1-u/v部 ...
- redis持久化机制【十三】
一.Redis提供了哪些持久化机制: redis的高性能是因为其所有数据都存在了内存中 ,为了使redis在重启之后数据仍然不丢失,需要将数据同步到硬盘中,这一过程就是持久化. redis支持两种方式 ...
- [bzoj1485][HNOI2009]有趣的数列_卡特兰数_组合数
有趣的数列 bzoj-1485 HNOI-2009 题目大意:求所有1~2n的排列满足奇数项递增,偶数项递增.相邻奇数项大于偶数项的序列个数%P. 注释:$1\le n\le 10^6$,$1\le ...
- codevs 3164 质因数分解
3164 质因数分解 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description (多数据)给出t个数,求出它的质因子个 ...
- {head first} --- networking 1
Head first系列的书确实非常好,深入浅出解说网络的组成.让曾经那些生涩的概念生动起来. Chapter 1 维修物理网络 CAT5电缆: 两端为RJ-45接头(水晶头).内部为UTP(非屏蔽双 ...