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

上述是两个 如果是多个关联呢?

时间: 2024-12-28 18:00:36

Unity3d学习 预设体(prefab)的一些理解的相关文章

Unity3D 基于预设(Prefab)的泛型对象池实现

背景 在研究Inventory Pro插件的时候,发现老外实现的一个泛型对象池,觉得设计的小巧实用,不敢私藏,特此共享出来. 以前也看过很多博友关于对象池的总结分享,但是世界这么大,这么复杂到底什么样的对象池才是好的呢,我们发现通用的对象池未必适应所有的环境,比如基于UI的局部(从某个Scene,到某个Dialog)对象池,范围不同,需要的对象池就有不同的要求.本文就是介绍一种基于预设(Prefab)的局部UI对象池. 通用信息提示窗口的实现http://www.manew.com/thread

Unity3D学习笔记之三Prefab组件的使用

本次教程,我们来创建一个简单的Prefab组件. 教程参考自人人素材翻译组出品的翻译教程<Unity游戏引擎的基础入门视频教程>. 说到Prefab,中文翻译为预设体,在Unity官方的书本<Unity4.X从入门到精通>中的解释是:可以理解为是一个游戏对象及其组件的集合,目的是使游戏对象及资源能够被重复使用.相同的对象可以通过一个预设体来创建,此过程可理解为实例化. 存储在项目文件中(Project视图)的状态时,预设体作为一个资源,可应用在一个项目中的不同场景中.当拖动预设体到

Unity学习笔记13——代码动态加载Prefab预设体

在进行一些功能开发的时候,我们常常将一些能够复用的对象制作成.prefab的预设物体,然后将预设体存放到Resources目录之下,使用时再动态加载到场景中并进行实例化.例如:子弹.特效甚至音频等,都能制作成预设体. 一.预设动态加载到场景: 一个预设体要能够通过代码控制在场景中进行显示,需要三个步骤,这里我们以动态加载怪物血条为例子分析一个常见的误区: 1.预设体资源加载: //加载预设体资源 GameObject hp_bar = (GameObject)Resources.Load("Pr

【Unity】3.2 利用预设(Prefab)制作可复用的组件

分类:Unity.C#.VS2015 创建日期:2016-04-02 一.简介 预制体(Prefab,也叫预设)是"存储在工程视图(Project View)中"的一种特殊的资源,是一种可重复使用的游戏对象(GameObject)的容器. 如果在Project中有多个预制体(Prefab),为了容易查找,可将这些预制体全部保存到Project视图中Assets文件夹的Prefabs子文件夹下. Prefabs子文件夹下的的所有预制体都可以放入到多个场景中,而且即使在同一个场景中仍然可以

Unity -- 材质-Material和预设体-Prefabs

材质(Materials)用来把网格(Mesh)或粒子渲染器(Particle Renderers)贴到游戏对象上.他们在定义对象怎么被显示发挥重要组成部分.材质包括用于呈现网状或颗粒着色器的参考,所以这些组件不能在没有材质的情况下显示.Material这个需要结合Shader来讲,计算机图形学里本身就没有Material这个东西,引擎加入这个其实是在shader和主程序之间搭建了一座桥梁,可以说Material是一个着色器管理器,所以很多接口都是对shader的控制.这里我们先讲Materia

[Unity3D]使用碰撞体做触发器实现自动开门

在游戏制作中触发器的使用非常的方便也非常实用.这一张我们简单介绍一下如何使用一个简单的触发器来实现自动开门关门的效果. 首先确保你已经对门进行了动画的设置. 具体流程如下. 选择Window->Animation打开动画窗口,选中需要添加动画的门之后点击红色按钮创建新动画. 选中一个需要添加动画的要素之后(比如Postion.x),点击添加关键帧按钮: 拖动时间轴,在动画终点的位置放手: 在场景中拖动那个门到想要停止的位置,创建动画终点的关键帧: 点击Animation面板上的播放键,可以预览一

【蓝鸥Unity开发基础三】课时12 预设体

推荐视频讲师博客:http://11165165.blog.51cto.com/ 预设体 预设体能够使游戏对象和资源重复使用 相同的游戏对象可以使用同一个预设体来创建 对预设体进行修改后,所有游戏对象都会相应改变 把预设体作为的一个模板原型,在使用的过程中,我们可以把预设体拖至场景中来创建一个新的游戏对象,能够让我们的游戏对象和资源能重复利用,并且对于预设体进行修改,可以对当前所以的游戏对象发生一样的修改. 接下来我们在Unity中来演示一下 1.预设体的创建--创建一个Cube--创建一个材质

【浅墨Unity3D Shader编程】之十一 深入理解Unity5中的Standard Shader(三)&amp;屏幕像素化特效的实现

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/50095705 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 本文工程使用的Unity3D版本: 5.2.1  概要:续接上文,本文进一步讲解与分析了上文未讲完的Unity5中Standard Shader正向基础渲染通道源码的片段着色实现部分,以及对屏幕像素化后期特效进行了实现. 同

unity3d学习笔记(十九)--ngui制作3d人物头顶的头像和血条

原地址:http://blog.csdn.net/lzhq1982/article/details/18793479 本系列文章由Aimar_Johnny编写,欢迎转载,转载请标明出处,谢谢. http://blog.csdn.net/lzhq1982/article/details/18793479 先上张图,自己做的一个demo. 这里的人物头像和血条是在3d世界生成的,所以有真正的纵深感和遮挡关系,废话不多说,看我是怎么实现的. 第一步,先在UI Root里制作头像和血条. 这个制作步骤基