第十一课 Unity编辑器创建的资源优化_预制体和材质篇(Prefabs和Materials)详解

ops/2024/12/27 0:57:12/

预制体(Prefabs)

Unity中的预制体是用来存储游戏对象、子对象及其所需组件的可重用资源,一般来说预制体资源可充当资源模版,在此模版基础上可以在场景中创建新的预制体实例。

使用预制体的好处

  • 由于预制体系统可以自动保持所有实例副本同步,因此可以比单纯地简单复制粘贴游戏对象做到更好的对象管理。
  • 此外通过预制体嵌套(Nested Prefabs)可以将一个预制体嵌套到另一个预制体中,从而创建多个易于编辑的复杂游戏对象层级视图。
  • 可以通过覆盖各个预制体实例的设置来创建预制体变体(Prefabs Variant),从而可以将一系列覆盖组合在一起形成有意义预制体的变化。

嵌套预制体与单预制体相比的优点与缺点

优点:

  1. 嵌套预制体方便预制体管理,方便资源重复利用,易于统计场景复杂度
  2. 美术制作时可以比较合理的分配UV,和贴图利用率
  3. 方便关卡设计人员发挥,充分合理利用资源
  4. 嵌套预制体比较方便利用工具做LOD,LOD效果也比较好
  5. 嵌套预制体修改方便,只需修改子预制体就可以做到所有嵌套预制体同步
  6. 比较方便做场景遮挡剔除,可以做到精细的遮挡剔除优化效果

缺点:

  1. 手动做Bundle依赖时要按Scene方式处理,依赖关系较为复杂
  2. 可能会增加材质数量与Drawcall数量
  3. 不太适合做大规模远景对象。
  4. 美术与关卡设计人员要充分考虑组合复杂度与特例场景显示,避免重复性和单一性,需要更多的沟通成本
     

使用Prefab变体的一些限制

- 不能改变本体Prefab游戏对象 (GameObject)层级
- 不能删除本体Prefab中的游戏对象,但可以通过Deactive游戏对象来达到与删除游戏对象同样的效果
- 对于Prefab变体要保持其Override属性的变化,不能通过Apply to base把这些变化应用到本体Prefab上,这样会破坏基础Prefab的结构和功能。

材质(Materials)

材质球是决定物体如何渲染的重要功能。虽然这是一个熟悉的特性,但如果使用不当,它很容易导致内存泄漏。

简单地访问一个参数将复制它

关于Material,最重要的是要记住,它们可以简单地通过访问它们的参数来复制。而且很难注意到它正在被复制。 

Material material;
void Awake()
{material = renderer.material;material.color = Color.green;
}

这是一个简单的过程,将材质的颜色属性设置为color .green。

渲染器的材质是重复的。复制的对象必须是显式的,

使用实例删除重复的Material

Material material;
void Awake()
{material = renderer.material;material.color = Color.green;
}
void OnDestroy()
{if (material != null){Destroy(material)}
}

以这种方式销毁重复的材料可以避免内存泄漏。

彻底清理生成的材质球

动态生成的材料是导致内存泄漏的另一个常见原因。 确保在使用完生成的材料后销毁它们。

Material material;void Awake()
{
material = new Material(); // Dynamically generated material
}void OnDestroy()
{if (material != null){Destroy(material); // Destroying a material when you have finished using it}}

材料应该在使用完后销毁(OnDestroy)。

根据项目的规则和规范,在适当的时间销毁材料。

如果项目中无法避免new材质球,可以使用对象池管理材质球

使用材质属性快来替换Material属性操作

通过MaterialPropertyBlock的方式来进行优化

具体相关操作和例子见如下文章《使用MaterialPropertyBlock来替换Material属性操作》。不过这种方法在URP下不适用,会打断SRP Batcher。

材质属性块被用于Graphics.DrawMesh和Renderer.SetPropertyBlock两个API,当我们想要绘制许多相同材质但不同属性的对象时可以使用它。例如你想改变每个绘制网格的颜色,但是它却不会改变渲染器的状态。

colorID = Shader.PropertyToID("_Color");prop = new MaterialPropertyBlock();listProp[i].GetComponent<Renderer>().GetPropertyBlock(prop);
prop.SetColor(colorID, new Color(r, g, b, 1));listProp[i].GetComponent<Renderer>().SetPropertyBlock(prop);    

同时我也通过Profiler的Memory模块,切换进Detailed选项,对其进行采样,可以发现在Sence Memory下面会有Material的拷贝(材质操作导致,而材质属性操作不会)。这也验证了操作材质时会有实例化存在,而使用材质属性块则不存在实例化。

今天是2024年12月1日

重复一段毒鸡汤来勉励我和你

你的对手在看书

你的仇人在磨刀

你的闺蜜在减肥

隔壁的老王在练腰

而你在干嘛?


http://www.ppmy.cn/ops/139336.html

相关文章

神经网络和支持向量机的基础——感知机模型

一、感知机模型的原理 感知机模型&#xff0c;也被称为神经元模型&#xff0c;其设计灵感来源于生物神经元的运行机制。它模拟了神经元的信息接收、处理和输出的过程&#xff0c;从而实现了对未知数据的分类。感知机模型的核心是线性回归与符号函数的结合。具体来说&#xff0…

预训练模型与ChatGPT:自然语言处理的革新与前景

目录 一、ChatGPT整体背景认知 &#xff08;一&#xff09;ChatGPT引起关注的原因 &#xff08;二&#xff09;与其他公司的竞争情况 二、NLP学习范式的发展 &#xff08;一&#xff09;规则和机器学习时期 &#xff08;二&#xff09;基于神经网络的监督学习时期 &…

<工具 Claude Desktop> 配置 MCP server 连接本地 SQLite, 本机文件夹(目录) 网络驱动器 Windows 11 系统

也是在学习中... 起因&#xff1a; 抖音博客 艾克AI分享 他的视频 #143《Claude开源MCP彻底打破AI的信息孤岛》 提到: Claude开源的MCP太强了&#xff0c;视频后面是快速演示&#xff0c;反正看了好几遍也没弄明白。菜单都不一样&#xff0c;感觉用的不是同一家 Claude. 探…

如何将快捷指令添加到启动台

如何将快捷指令添加到启动台/Finder/访达&#xff08;Mac&#xff09; 1. 打开快捷指令创建快捷指令 示例创建了一个文件操作测试的快捷指令。 2. 右键选择添加到程序坞 鼠标放在待添加的快捷指令上。 3. 右键添加到访达 鼠标放在待添加的快捷指令上。 之后就可以在启…

C#VB.NET开发整体一键国际化显示

第一章链接 第二章 窗口多国语言显示 在第一章时我们已经了解如何对内容进行多语言化下面讲解如何对窗口多语言显示 在实际开发中单个窗体内可能有很多控件,如果我们对每个控件使用Mu方法进行赋值是异常繁琐的如下 Button1.Text"显示".Mu(); 在对窗口进行多语言化SG…

C++中的操作系统级信号处理——signal与sigaction

在多进程的编程中,信号是一种非常重要的多进程通讯手段。而进程间的信号很大情况是和操作系统是相关的,或者说很多信号是从操作系统中过来的。 我们这一篇就来说一下操作系统的信号。 操作系统中的信号其实在操作系统中可以称作是中断,可以理解为一个循环执行的程序中突然…

第2章:CSS基本语法 --[CSS零基础入门]

CSS&#xff08;层叠样式表&#xff0c;Cascading Style Sheets&#xff09;是用来描述HTML或XML&#xff08;包括各种XML&#xff1a;SVG, MathML 或 XHTML&#xff09;等文档的外观和格式的语言。以下是CSS的基本语法&#xff1a; 1.选择器 1.元素选择器 元素选择器是基于…

手机实时提取SIM卡打电话的信令声音-蓝牙电话如何适配eSIM卡的手机

手机实时提取SIM卡打电话的信令声音 --蓝牙电话如何适配eSIM卡的手机 一、前言 蓝牙电话的海外战略中&#xff0c;由于海外智能手机市场中政策的差异性&#xff0c;对内置eSIM卡的手机进行支持是非常合理的需求。Android系列手机中&#xff0c;无论是更换通信运营商&#xf…