第十六章 预制件prefab(上)

本章节我们介绍一下“预制件”,也有人叫“预制体”,也就是Prefab。在游戏世界中,那些自然环境的游戏对象,我们可以提前创建在场景中,这个大家能够理解。但是,有些游戏对象,需要根据游戏逻辑来通过代码生成,例如刷新怪物,触发机关等等。Unity 的预制件系统允许创建、配置和存储游戏对象及其所有组件、属性值和子游戏对象作为可重用资源(它的本质就是一个资源文件,相当于编程里面的类文件,通过它可以实例化多个对象)。预制件资源充当模板,在此模板的基础之上可以在场景中创建新的预制件实例。对预制件资源所做的任何编辑都会自动反映在该预制件的实例中,因此可以轻松地对整个项目进行广泛的更改,而无需对资源的每个副本重复进行相同的编辑。

预制体是用来存储一个游戏对象的所有组件,属性和子对象,这样就成为了一个可重复使用的资源文件。当需要多次重复使用这个游戏对象时,便可以使用预制体来创建。举一个简单的例子,我们会在游戏世界中创建同一种怪物模型的实例,显然我们不可能将怪物模型一个个的拖拽到游戏世界中,并且这些怪物会死亡消失,也会重新刷新。因此,合理的解决方案应该是,每一种怪物都应该是一个预制体,然后我们可以通过预制体来创建不同的怪物实例,这就是预制体的优势。当然,预制体更重要的是对游戏对象的“封装”,预制体不仅仅是网格模型,同时还可以包含各种功能组件以及脚本,这样的预制体就能承载更多的内容。

接下来,我们回到ScriptDemo项目工程中,创建一个新的“SampleScene7”场景,然后创建一个“Cube”游戏对象和“CubePrefab.cs”脚本文件,并将其附加在一起。

 

接下来,我们在“CubePrefab.cs”脚本文件实现Cube自旋转的代码,如下所示:

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

public class CubePrefab : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.Rotate(new Vector3(0, 1, 0));
    }
}

为了更好的观察Cube,我们将摄像机向上Y轴方向移动5个单位,且X轴方向旋转20度,这样就能俯视Cube了。

接下来,我们保持相机选中状态,我们点击菜单栏“GameObject”->“Align View to Selected”

然后我们Play当前工程,效果如下:

接下来,我们要做的就是创建十个这样的旋转立方体,粗暴的办法就是再创建9个Cube,然后将“CubePrefab.cs”脚本文件分别附加到这9个Cube身上,显然这种方式不太合理。此时,我们就需要借助预制体来实现了。首先我们要创建预制体,创建的方法非常简单,就是将“Hierarchy”视图中的Cube游戏对象拖拽到“Project”视图中。

这样一个名称为“Cube”的预制体就创建成功了,同时在“Hierarchy”视图中“Cube”的名称颜色会变成蓝色,代表这个名称为“Cube”的游戏对象是一个预制体实例。

请注意,预制体本质是一个资源文件,也就是“Project”视图中的“Cube”文件,如果我们去我们的工程目录下的Asset文件夹下面查看,就能看到一个“Cube.prefab”的预制体文件。

那么“Hierarchy”视图中“Cube”又是什么呢,它其实就是预制体的一个实例而已。我们可以将预制体理解为面向对象变成中的类文件,类就是一个模板,我们可以根据这个类实例化很多很多的对象,这些对象都拥有类中实现的功能,只是每一个对象的内部数据不一样。既然“Cube.prefab”是一个预制体,它与类模板概念相同,我们就可以根据这个预制体来实例化很多很多的游戏对象,也就是“Hierarchy”视图中“Cube”。将一个预制体实例化为一个游戏对象,需要借助“GameObject.Instantiate”方法,该方法有三个参数,第一个就是预制体文件,第二个就是游戏对象的位置,第三个就是游戏对象的朝向。接下来,我们来实现这个功能。我们首先删除调当前场景中的“Cube”游戏对象。然后,我们创建一个“CubePrefabManager.cs”的脚本文件,并将其附加到摄像机上面去。

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

public class CubePrefabManager : MonoBehaviour
{
    // 预制体文件
    public GameObject prefab;

    // 预制体实例数量
    private int count;

    // Start is called before the first frame update
    void Start()
    {
        // 加载预制体文件
        prefab = AssetDatabase.LoadAssetAtPath("Assets/Cube.prefab", typeof(GameObject)) as GameObject;
    }


    // Update is called once per frame
    void Update()
    {
        // 按下空格键就生成一个自旋转的Cube
        if (Input.GetKeyDown(KeyCode.Space))
        {
            count++;
            Vector3 pos = new Vector3(count * 2, 0, 0);
            GameObject.Instantiate(prefab, pos, Quaternion.identity);
        }
    }
}

不要忘了,将“CubePrefabManager.cs”脚本附加到相机上。以上代码有三点需要解释。第一,我们的prefab文件需要载入,它的本质就是GameObject类型。第二,我们按下空格键来根据prefab来创建一个游戏对象实例。第三,创建的prefab实例的位置依次向右递增,但是他们的朝向(旋转)统一是Quaternion.identity(不旋转/默认值)。接下来,我们就可以Play当前工程,查看效果。

当我们实例化出来四个Cube游戏对象实例的时候,他们的名称都是“Cube(Clone)”,也就是复制克隆出来的。这个应该比较容易理解。我们从Hierarchy层次面板中就能看到。

最后我们要说的就是关于prefab文件的加载。上面的代码中,我们使用了AssetDatabase.LoadAssetAtPath方法(还有使用“using UnityEditor;”)。其实我们我们可以将“Cube.prefab”文件放置工程目录“Assets/Resources”下。这个“Resources”目录是一个特殊的目录,它对应Unity API中的Resources类,该类有一个Load静态方法,可以直接读取下面的预制体文件。接下来,我们就创建“Resources”,并将“Cube.prefab”复制到这个文件夹下,重命名为“Cube2.prefab”,如下图所示:

然后我们修改“CubePrefabManager.cs”代码:

// 加载预制体文件
//prefab = AssetDatabase.LoadAssetAtPath("Assets/Cube.prefab", typeof(GameObject)) as GameObject;
prefab = Resources.Load<GameObject>("Cube2 ");

当然,此方法并不只是加载prefab资源文件,还可以加载其他文件(例如贴图)。注意,这个方法不需要我们使用“using UnityEditor;”,并且参数为预制件名称(不需要文件后缀)。为了更好的管理这些资源文件,我们可以继续在“Assets/Resources”规划子目录管理他们。那么,在使用Resources.Load加载的时候,只需要在参数中按照“xxx/yyy”方式加载即可。这种方式还是比较推荐的。接下来,我们Play工程,看到之前一样的效果了。

还有两一种更加省时省力的办法。由于我们声明的prefab变量是public类型,因此可以在Inspector检视面板中编辑这个prefab变量。我们在Hierarchy层次视图中点击选中相机,然后查看Inspector检视面板,如下所示:

然后,我们可以直接将“Project”视图中的“Cube”预制体拖拽到这个属性值上面。

这样,我们就不用使用代码来加载这个预制体文件啦。

我们注释调start中的代码,如下

    // Start is called before the first frame update
    void Start()
    {
        // 加载预制体文件
        //prefab = AssetDatabase.LoadAssetAtPath("Assets/Cube.prefab", typeof(GameObject)) as GameObject;
        //prefab = Resources.Load<GameObject>("Cube2");
    }

接下来,我们重新Play工程,就能看到之前一模一样的效果了。我们就不添加效果图了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/16198.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

外卖项目优化-01-redis缓存短信验证码、菜品数据、Spring Cache(注解开发缓存)、(注解开发)缓存套餐数据

文章目录 外卖项目优化-01课程内容前言1. 环境搭建1.1 版本控制解决branch和tag命名冲突 1.2 环境准备 2. 缓存短信验证码2.1 思路分析2.2 代码改造2.3 功能测试 3. 缓存菜品信息3.1 实现思路3.2 代码改造3.2.1 查询菜品缓存3.2.2 清理菜品缓存 3.3 功能测试3.4 提交并推送代码…

Vue(简单了解Cookie、生命周期)

一、了解Cookie 类似于对象响应携带数据 输入用户名密码跳转到指定页面 点击指定页面中其中一个按钮跳转到另一个指定页面&#xff08;再不需用输入用户名密码&#xff09; 例如现在很多浏览器实现七天免密登录 简单理解&#xff1a;就是在网站登录页面之后&#xff0c;服务…

二叉树的遍历及相关衍生

二叉树的遍历及相关衍生 前言二叉树的遍历建树二叉树的遍历遍历的分类代码部分 遍历根的应用打印树中的每个数据代码部分 遍历计算树节点个数代码部分 计算二叉树的深度思路代码部分 第k层个数 结束 前言 如标题所示&#xff0c;在这里我们要研究的是二叉树的遍历。 为什么不…

郑哲:学习、应用初探与探索创新 | 提升之路系列(四)

导读 为了发挥清华大学多学科优势&#xff0c;搭建跨学科交叉融合平台&#xff0c;创新跨学科交叉培养模式&#xff0c;培养具有大数据思维和应用创新的“π”型人才&#xff0c;由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

ros2 foxy创建一个包和节点-ubuntu20.04

文章目录 创建工作区目录创建包和节点colcon build编译CMakeLists.txt文件find_packageadd_executable package.xml面相过程的方式生命一个节点以面向对象的方式创建一个节点 创建工作区目录 mkdir -p ~/ros2_ws/src cd ~/ros2_ws我们创建了两个目录&#xff0c;ros2_ws和在他…

【电商必学】 WhatsApp 全新攻略:什么是交互式消息模板

网购与WhatsApp等社交通讯平台有着密不可分的关系&#xff0c;为什么这么说呢&#xff1f;因为基本上所有的网购的平台都会提供查询、下单方式给客户&#xff0c;而WhatsApp是全世界使用率最高的通讯平台&#xff0c;所以大部分电子商户都会选择WhatsApp Business与电子商务连接…

Linux pthread线程操作 和 线程同步与互斥操作

在Linux系统中玩线程&#xff0c;使用pthread&#xff0c;这篇博客记录如何创建线程和使用线程和线程的同步与互斥。 还有一份nginx线程池的代码供大家阅读学习&#xff01; 目录 一、简介 什么是线程 线程的优点、缺点 线程的应用场合 二、线程的使用 1. 创建线程 - p…

高并发场景下JVM调优实践

一、背景 2021年2月&#xff0c;收到反馈&#xff0c;视频APP某核心接口高峰期响应慢&#xff0c;影响用户体验。 通过监控发现&#xff0c;接口响应慢主要是P99耗时高引起的&#xff0c;怀疑与该服务的GC有关&#xff0c;该服务典型的一个实例GC表现如下图&#xff1a; 可以…

最值得学的编程语言是哪个?

如果让我推荐的话&#xff0c;我肯定首选是python啦&#xff01; 编程语言是一个计算机的概念&#xff0c;在我们有了计算机以后&#xff0c;想让它帮助我们做事情&#xff0c;就要通过计算机语言和它进行对话、交互&#xff0c;计算机语言能够被计算机所执行&#xff0c;完成…

【MFAC】基于全格式动态线性化的无模型自适应控制(Matlab代码)

例题来源&#xff1a;侯忠生教授的《无模型自适应控制&#xff1a;理论与应用》&#xff08;2013年科学出版社&#xff09;。 &#x1f449;对应书本 4.4 单输入单输出系统(SISO)全格式动态线性化(FFDL)的无模型自适应控制(MFAC) 上两篇博客分别介绍了基于紧格式和偏格式动态线…

Linux命令集(Linux常用命令--cat指令篇)

Linux命令集&#xff08;Linux常用命令--cat指令篇&#xff09; Linux常用命令集&#xff08;cat指令篇&#xff09;4.cat(concatenate)1. 查看文件内容&#xff1a;2. 连接多个文件&#xff1a;3. 创建文件并通过终端写入内容4. 输出内容编号 Linux常用命令集&#xff08;cat指…

【英语】大学英语CET考试,写作部分(论述文+应用文,6篇范文)

文章目录 3项评分标准&#xff08;内容&结构&#xff0c;语言&#xff09;0.1 论述文个人小结 1、论述文&#xff1a;审题与功能句2、论述文&#xff1a;修饰内容和名言模板3、论述文&#xff1a;现象作文&利弊分析4、论述文&#xff1a;给出权威论据和有侧重的现象5、…

在amd64与arm上用paddlelite部署paddelOCR(Ascend硬件)

由于部署的硬件是华为昇腾 NPU&#xff08;Ascend310&#xff09;&#xff0c;参考网址https://www.paddlepaddle.org.cn/lite/v2.10/demo_guides/huawei_ascend_npu.html#npu-paddle-lite 先拉取paddlelite用来编译库 git clone https://github.com/PaddlePaddle/Paddle-Lit…

反转字符串——leetcode344、leetcode541

文章目录 简单反转字符串题目详情分析Java完整代码 反转链表进阶问题题目详情分析Java完整代码 简单反转字符串 题目详情 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须…

RMAN-03009、ORA-19566数据文件坏块报错处理方法

在备份数据库的时候&#xff0c;出现RMAN-03009、ORA-19566报错&#xff1a; RMAN-03009: backup 命令 (c3 通道上, 在 04/29/2023 10:58:11 上) 失败 ORA-19566: 超出损坏块限制 0 (文件 E:\APP\ADMINISTRATOR\ORADATA\JHSEMR\JHEMR2.DBF) 继续执行其他作业步骤, 将不重新运行…

Github创建一个新仓库,关联本地数据并上传文件的图文步骤

工作中&#xff0c;我们经常会使用github来承享别人的代码果实&#xff0c;同时我们也会把自己的成果分享给别人&#xff0c;互相帮助。 今天的这篇图文教程非常重要&#xff0c;目标是使用Github来创建一个远程仓库&#xff0c;并和本地仓库对接&#xff0c;同时要做上传新内容…

区域医疗云his系统源码,具有可扩展、易共享、易协同的优势

云HIS系统采用SaaS软件应用服务模式&#xff0c;提供软件应用服务多租户机制&#xff0c;实现一中心部署多机构使用。相对传统HIS单机构应用模式&#xff0c;它可灵活应对区域医疗、医疗集团、医联体、连锁诊所、单体医院等应用场景&#xff0c;并提升区域内应用的标准化与规范…

python处理图像的各种技术镜像、旋转、遮挡、叠加、条带化

2.6 图像镜面对称 1、将图像水平镜面转换。 2、将图像垂直镜面转换。 import random #导入模块 import numpy as np import matplotlib.pyplot as plt a plt.imread("1.jpg") # 将图像沿着水平方向重复三次。 ba.copy() da.copy() # 将图像水平镜面转换。&…

LeCun、田渊栋参与撰写,70页「自监督学习」大全

来源 | 机器之心 微信号&#xff1a;almosthuman2014 「关于自监督学习&#xff0c;你想知道但又不敢问的一切都在这里了。」图灵奖得主、Meta 人工智能首席科学家 Yann LeCun 刚刚发了这样一则推文。 在推文中&#xff0c;LeCun 介绍了他和 Meta 人工智能研究院研究员、研究经…

javaEE初阶 — 服务器版本的表白墙案例

文章目录 原来版本涉及的问题设计程序1 点击提交2 页面加载 实现后端代码1 新建一个 Maven 项目。2 按照之前第一个 Servlet 程序的步骤来进行设置3 新建一个 MessageServlet 类 实现前端代码1 点击提交的时给服务器发送一个 POST 请求2 在页面加载时发送一个 GET 请求3 将数据…