您好,欢迎来到Unity之家!   unity.jb51.net 
  • 首 页
  • 你问我答
  • 当前位置:首页 > 程序开发 > 代码编程 >
    如何在一个预设(Prefab)物件上再预设(Prefab)出一个物件,Prefab
    时间:2014-12-12 10:36 来源:互联网 作者:脚印 浏览:收藏 挑错 推荐 打印

    最近在做UI部分中遇到了这样的问题,就是Prefab里面预制了Prefab。可是在Unity里面一旦Prefab预制了Prefab那么内部的 Prefab就失去关联。导致与如果要改内部的Prefab需要把所有引用的地方全部改一遍。今天在逛国外网站看到了一个老外的思路,原文在这里  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拖入下方。



    (责任编辑:脚印)
    免责声明:Unity之家部分内容来源于互联网,如有侵权,请联系我们,本站将立即进行处理。