Unity快速入门教程-详解预制体(Prefab)及其实例化Instantiate

Posted 边敲代码边吃草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity快速入门教程-详解预制体(Prefab)及其实例化Instantiate相关的知识,希望对你有一定的参考价值。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

博主刚学习unity的时候,在网上找预制体相关的博客,可是很难找到一篇凝练且通俗易懂介绍预制体的文章,浪费了不少时间且难以理解一些文章的内容。自己摸索学习了一段时间过后,总算对预制体有了一定的了解,现在本篇文章将凝练的讲一讲unity中的预制体及其实例化。


提示:以下是本篇文章正文内容,下面案例可供参考

一、预制体(Prefab)是什么?

1.1预制体简介

大家平时点的外卖,其菜品很多就是通过预制菜制作的,预制菜的主要特点是规格统一且经过简单加工即可制成成品。我们可以把现实中的预制菜比作unity中的预制体,厨师加工预制菜的过程就是预制体实例化的过程,这里的厨师其实就是instantiate函数,通过函数将预制体实例化。厨师用预制菜制作出了一道成品菜,就是instantiate函数实例化了一个预制体,将该预制体呈现在场景中。

1.2预制体是什么样子的?

预制体可以有多种元素组合而成,所谓的元素一般是游戏素材,比如图片,模型等,将所有的元素打包成一个物体,这个物体就是所谓的预制体。
如图样例就是一个命名为【GameObject】的预制体,它包括了场景中出现的所有元素(房子,马路,树木,栅栏,草丛),函数实例化该预制体后,游戏场景中就会一齐出现房子马路等元素的一个集合。

1.3预制体作用与用途

在一个游戏项目中,场景可能就是由许多个预制体拼凑而成,每个预制体组成了场景中的一点部分元素,比如要制作一个无限大的地图,通常游戏就会设置当主视角接近场景边界的时候,就往外随机生成一个预制体场景,这样就能实现无限大地图的效果。预制体的使用就会大大方便对地图元素的管理。
如果你要制作一把游戏枪械,当枪械激发时你想做出一颗颗子弹出枪膛的效果,那么子弹也可以做成一种预制体,不断在枪口实例化,且实例化之后沿着枪口方向移动。

二、制作一个预制体

2.1制作预制体示例

我们首先将素材拖入场景界面,可以根据你对游戏场景的设计,摆出你希望的预制体的样子,你所设计的样子,就是以后预制体实例化的样子。

然后我们创建一个空的物体,将我们所添加的元素全部并入到该空物体,成为其子项。

最后,我们将【GameObject】拖入到Project的一个文件夹,至此,一个预制体就制作完成了。以后要使用该预制体的时候,我们就可以从Project中实例化该预制体。保存好之后就可以把场景【Hierarchy】里面的【GameObject】删去了,保存【Project】里面的源预制体即可,因为我们实例化调用的是项目里面的源预制体。

2.2预制体实例化

要实例化一个预制体,我们首先要代码获取到源预制体,然后在通过Instantiate函数将获得的源预制体实例化。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour

    //预制体是用GameObject类型
    public GameObject prefab; 


我们可以通过pubic来获取外部的源预制体,pubic可以在编辑器界面生成一个面板窗口,随后将源预制体拖放到【Test】脚本下的【Prefab】窗口。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour

    public GameObject prefab;
    private void Start()
    
        Instantiate(prefab);
    

在脚本中加上Instantiate(prefab),保存代码返回编辑器中点击play运行,即可简单的将预制体实例化,生成刚刚所设计的场景在游戏中。


总结

本文只是简单的介绍了Instantiate函数的最简单用法,Instantiate函数还可以设置更多参数,比如初始化预制体的位置,旋转角度等,比如

      Instantiate(prefab, new Vector3(0,0,0), Quaternion.identity);

Unity3.2 利用预设(Prefab)制作可复用的组件

分类:Unity、C#、VS2015

创建日期:2016-04-02

一、简介

预制体(Prefab,也叫预设)是“存储在工程视图(Project View)中”的一种特殊的资源,是一种可重复使用的游戏对象(GameObject)的容器。

如果在Project中有多个预制体(Prefab),为了容易查找,可将这些预制体全部保存到Project视图中Assets文件夹的Prefabs子文件夹下。

Prefabs子文件夹下的的所有预制体都可以放入到多个场景中,而且即使在同一个场景中仍然可以多次使用。

向场景中添加一个预制体就是创建该预制体的一个实例。另外,由于场景(Scene)中所有预制体的实例都会自动链接到Project中的原始预制体(Prefab),因此这些实例本质上就是原始预制体的克隆。或者说,不论场景中有多少个预制体实例,只要仅仅对Project中某个Prefab作出任何更改,你就会看到这些更改马上就能应用于场景中该Prefab的所有实例。

1、在工程视图(Project)中创建预制体(Prefab)

要在Project中创建一个预制体(Prefab),只需将你在场景(Scene)中创建的一个游戏对象 (GameObject)拖放到工程视图(Project View)中的某个Prefab中。

如果层级视图(Hierarchy)中的游戏对象(GameObject)的名称变成蓝色,表示Hierarchy中的该对象是一个已经制作好的预制体的实例。此时,你可以根据需要,决定是保留层级视图 (Hierarchy)中的这个实例还是删除这个实例,不论你是否保留,都不会影响Project中制作好的原始预制体。

2、在层次视图(Hierarchy)中创建预制体的实例

要在“当前场景中”创建一个“预制体的实例”,直接从工程视图(Project View)中将某个预制体拖放到场景(Scene)或层级视图(Hierarchy)中。

Hierarchy视图中的“蓝色”字体表示该对象是某个预制体的实例。

一旦你创建了预制体的实例,该实例就会自动链接到Project中的源预制体,并在层级视图(Hierarchy)中以“蓝色”文字显示。

image

在这个截图中,有3个游戏对象是蓝色,表示这都是预制体的实例。

3、在检视器(Inspector)中操作预制体

(1)粗体的含义

有时候你可能希望仅更改单个预制体实例的属性,同时还能保持与源预制体的链接完整,此时可看到该实例对应的变量名称变成了粗体,表示这个变量已被重写。注意,所有重写的属性都不会受到源预制体更改的影响。

(2)Select

如果你选择了某个预制体实例,并希望将所做的更改影响到所有实例,此时可直接在检视器(Inspector)中单击【Select】按钮来选择更改的原始预制体。

(3)Apply

如果希望用重写的值更新源预制体及其所有实例,可单击检视器(Inspector)中的【Apply】 按钮。注意,这种“应用”不会对“根位置”和“旋转”起作用,因为这会影响实例的绝对位置并导致所有实例放在同一个位置。但是,Apply会对根的任何子元素或祖先元素的位置和旋转起作用,因为它们是相对于根的变换来计算的。

(4)Revert

如果想放弃对特定实例的所有重写,可单击【(Revert)】按钮。

4、导入预制体

将网格资源放入Assets文件夹下时,Unity会自动导入文件,并生成一些类似于网格之外的看起来像预制体的东西。但是,这实际上不是预制体(Prefab),它只是资源文件本身使用的东西。

注意,资源(asset)图标与预设 (Prefab) 图标略有不同。

资源是作为一个游戏对象(GameObject)存在于场景中的实例,它链接到源资源而不是链接到预制体(Prefab)。你可以向该游戏对象(GameObject) 正常添加、删除组件,。但是你无法对资源本身作任何更改,因为这样会向资源文件本身添加数据!如果你希望创建一些可重复使用的东西,那你就应当把它制作成一个预制体。

选择一个资源实例时,检视器 (Inspector) 中的【Apply】按钮将被替换成【Edit】按钮。单击此按钮将为资源启动编辑应用程序(如 Maya 或 Max)。

二、Prefabs基本用法示例

经过上面的介绍,你应当已经从基本层面上了解了Prefabs的概念:Prefabs本质上是GameObjects(预定义的游戏对象)和Components(组件)组成的集合体,是可在游戏中重复使用的容器对象。

使用Prefabs可以方便地在运行时实例化复杂的GameObjects(游戏对象)。

1、创建游戏对象的方式

在Unity中,有两种创建对象(Game Object)的方式:

(1)方式1:全部用C#代码实现。这种方式使用C#代码从头开始创建并初始化游戏对象(GameObjects)。

(2)方式2:利用Prefabs实现。即:先制作预制体,运行时再通过代码实例化预制体。

与方式1相比,方式2(用Prefabs实现)有多个优势:

l 可以使用一行代码实例化Prefab,并具有完整功能。而使用代码创建等效游戏对象 (GameObjects),平均需要五行代码,还有可能需要更多。

l 可在场景 (Scene) 和检视器 (Inspector) 中快速设置、测试和修改预制体。

l 可以更改已实例化的预制体,而无需更改实例化预制体的代码。例如,可将一个简单的火箭更改成超级火箭,但无需更改代码。

2、示例—创建一堵墙

为了说明Prefabs的强大,让我们来看看可用得上Prefabs的一些基本情况:

(1)在不同位置,多次使用单块“砖”预制体来创建一堵墙。

(2)发射时,火箭发射器实例化一个飞行的火箭预制体。该预制体是一个包含一个网格(Mesh)、刚体 (Rigidbody)、碰撞器 (Collider) 和带有自己的拖尾粒子系统 (Particle System) 的子游戏对象 (GameObject)。

(3)机器人爆炸成许多碎片。此时完整的操作机器人已毁坏,替换成一个残破的机器人预制体。该预制体包含分成多个部分的机器人,所有部分均设有自己的刚体 (Rigidbodies) 和粒子系统 (Particle Systems)。有了预制体,你仅用一行代码就可以将一个对象替换成指定的预制体,从而让机器人炸成许多碎片。

该示例仅仅是为了说明“使用Prefab创建对象”与“使用代码创建对象”相比,前者(使用Prefab创建对象)的优势。

(1)实现方式1

首先演示“使用代码创建对象”的实现方式,因为只有比较,你才能理解这种方式有什么缺点。

先在ch03Demos工程的Project视图的Assets下创建一个名为Scripts的子文件夹,然后在该子文件夹添加一个名为Demo1的C#脚本:

image

双击Demo1脚本,Unity就会自动启动VS2015并自动在VS2015中打开Demo1.cs文件,而且解决方案资源管理器中Assets下的文件夹结构和Unity中的文件夹结构相同:

image

将Demo1.cs文件改为下面的内容:

using UnityEngine;
using System.Collections;

public class Demo1 : MonoBehaviour
{
    void Start ()
    {
        for (int y = 0; y < 5; y++)
        {
            for (int x = 0; x < 5; x++)
            {
                GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                cube.AddComponent<Rigidbody>();
                cube.transform.position = new Vector3(x, y, 0);
            }
        }
    }
}

保存该文件。

切换到Unity,选择主菜单的【GameObject】->【Create Empty】创建一个空游戏对象,再将Scripts文件夹下的Demo1脚本拖放到刚添加的空游戏对象中。

切换到Game视图,单击【播放】按钮观察执行效果。此时将看到完全用代码创建的立方体墙(由于默认使用了重力,墙会自动倒塌):

image

当然,由于没有添加纹理,所以此时看到的仅仅是一堵白色的墙(倒塌后还是一个一个的立方体)。若想执行附加操作,例如更改砖块纹理、摩擦力或刚体的质量,还需要再添加其他的代码,可见用这种方式实现起来有多么麻烦。

删除层次视图中刚创建的空游戏对象。

(2)实现方式2

第2种中实现方式是先创建一个“墙”预制体,然后再用“创建预制体实例”的办法来创建多堵墙。

步骤如下:

选择主菜单的【GameObject】->【3D Object】->【Cube】创建一个立方体:

image

此时,刚创建的Cube在层次视图中处于选中状态。

将Texture文件夹下的brick_D拖放到层次视图中的这个立方体上。

在Project视图的Assets文件夹下,添加一个Prefabs子文件夹:

image

鼠标右击Prefabs子文件夹,选择【Create】->【Prefab】:

image

将新添加的Prefab的名称更改为“Brick”。

将在层级视图中创建的立方体拖放到Project视图中刚创建的“Brick”上。

image

这样就创建好了一个名为“Brick”的预制体(或预设)。

创建预设 (Prefab) 后,在层次视图中添加的立方体(Cube)已经用不到了,可以从层级视图 (Hierarchy) 选中它,然后按Delete键删除。

重新添加一个空游戏对象 (GameObject)。

在VS2015解决方案资源管理器项目中的Scripts子文件夹下,添加一个文件名为Demo2.cs的C#脚本(Demo2.cs),然后将其改为下面的内容:

using UnityEngine;
using System.Collections;

public class Demo2 : MonoBehaviour
{
    public Transform Brick;

    void Start ()
    {
        for (int y = 0; y < 5; y++)
        {
            for (int x = 0; x < 5; x++)
            {
                Instantiate(Brick, new Vector3(x, y, 0), Quaternion.identity);
            }
        }
    }
}

按<F5>键将其附加到Unity,然后按<Shift>+<F5>键结束。

切换到Unity,将工程视图下的该脚本拖放到刚才添加的Cube上,这就为该对象添加了一个Demo2组件:

image

另外,此时检视器 (Inspector) 中将出现一个名为“Brick”的新变量,这个Transform类型的变量可以接受任何游戏对象 (GameObject) 或预制体。

从工程视图 (Project View) 中,将预制体“Brick”拖放到检视器 (Inspector)视图中的Brick变量的值上(作用是:创建预制体的实例作为Brick变量的值):

image

按下“播放 (Play)”,就会看到同时使用预制体和C#脚本创建的墙:

image

可见,这种方式实现的脚本代码不仅非常干净,而且可重复使用这个Brick预制体。

刚开始学习时,你可能想知道为什么要这样做,用第1种方式创建立方体不是更灵活和方便吗?为什么还要再搞一个Prefab呢?

这是因为使用Prefab,您可以在数秒之内就能完成对它的调整:

  • 想要添加或更改所有实例的质量?只需在预制体中添加一个刚体,并一次性调整刚体 (Rigidbody)的重力即可。
  • 想为所有实例使用不同的材质 (Material)?只需将材质 (Material) 拖放到预制体上一次。
  • 想要更改摩擦力?在预制体碰撞器中使用不同的物理材质 (Physic Material)就行了。
  • 想为所有立方体添加一个粒子系统 (Particle System)?向预制体中添加一次子对象即可。

当然,如果仅仅是为了学习操作步骤,找不到brick_D.jpg文件时,随便找一副其他的.jpg图片代替也行,反正目标就是给这堵用立方体构造的墙贴满图,理解其含义就行了。

以上是关于Unity快速入门教程-详解预制体(Prefab)及其实例化Instantiate的主要内容,如果未能解决你的问题,请参考以下文章

Unity入门计划基本概念-预制件 Prefab

获取某个Unity工程中的所有预制体

Unity3.2 利用预设(Prefab)制作可复用的组件

Unity学习笔记:预制件Prefab的创建和使用

Unity 3D 从入门到实践Unity 3D 预制体

Layabox 预制体prefab使用