Unity3d學習 預設體(prefab)的一些理解


之前一直在想如果要在Unity3d上創建很多個具有相同結構的對象,是如何做的,后來查了相關資料發現預設體可以解決這個問題!

預設體的概念: 組件的集合體 , 預制物體可以實例化成游戲對象.

創建預設體的作用: 可以重復的創建具有相同結構的游戲對象。

.1下面來講解一下如何制作一個簡單的預設體(上下為流程和結果圖):

  

  

.2 創建多個prefabs_new(代碼,結果圖):

 1 using UnityEngine;
 2 using System.Collections;
 3  
 4 //[ExecuteInEditMode]表示在編輯模式下運行(注意改變prefab的屬性其他屬性也會變)
 5 public class CreateInstance : MonoBehaviour {
 6     public GameObject prefabs = null;
 7     private Vector3 pos;
 8     void Start () {
 9         if (prefabs != null)
10         {
11             pos = new Vector3(0, 2.7f, -10.5114f);
12             for (int i = 0; i < 5; ++i)
13             {
14                 Object tmpObj = Instantiate(prefabs, pos , Quaternion.identity);
15                 pos.x = pos.x - 3;
16             }
17         }
18         else
19         {
20             Debug.Log("prefabs is null");
21         }
22     }
23 }

 

  

 如果(預設物C = 預設物B 和 預設物 A的組合) 則會形成 修改預設物A的數據不會影響預設物C中的內嵌數據,下面方法可以幫助解決!

 .4關於perfab之間的嵌套(主要是一個perfab數據修改了嵌套這個perfab的數據要做對應的更新):

    

關於預設體嵌套預設體的代碼(在實例化時會拿到最新的perfab數據):

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

  上述是兩個 如果是多個關聯呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM