呆呆敲代码的小Y头像
关注
【100个 Unity实用技巧】☀️ | Material vs sharedMaterial 区别封面图

【100个 Unity实用技巧】☀️ | Material vs sharedMaterial 区别

请添加图片描述


Unity 小知识 大智慧

  • 🎬 博客主页:https://xiaoy.blog.csdn.net

  • 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉

  • 🎄 学习专栏推荐:Unity系统学习专栏

  • 🌲 游戏制作专栏推荐:游戏制作

  • 🌲Unity实战100例专栏推荐:Unity 实战100例 教程

  • 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

  • 📆 未来很长,值得我们全力奔赴更美好的生活✨

  • ------------------❤️分割线❤️-------------------------

请添加图片描述


Unity 实用技巧学习

Material vs sharedMaterial 区别

归属:Renderer组件(MeshRenderer/SkinnedMeshRenderer等)

renderer.material
renderer.sharedMaterial

核心区别一句话

  • sharedMaterial:共享材质,直接指向Project里原始材质资源,多个物体共用同一份资源实例。
  • material:实例化材质,第一次访问时,复制一份全新的Material实例给到当前Renderer,修改只影响本物体。

底层行为

1. sharedMaterial(共享)

  • 直接引用Assets中的材质资源文件。
  • ✅多个Renderer可以同时指向同一个sharedMaterial。
  • ⚠️修改它,会直接修改Project原始材质资源!退出运行模式修改依然保留,会污染资源。
  • 运行模式下改sharedMaterial = 修改源资源,非常危险。

2. material(实例材质)

第一次读取.material的时候Unity自动Instantiate复制一份材质实例

  1. 首次访问:把sharedMaterial复制一份独立Material实例给到渲染器;
  2. 后续再读material,返回这个已经实例化好的副本;
  3. 修改material的颜色、Shader属性,只影响当前物体,其他物体不受影响;
  4. ⚠️运行时生成的材质实例属于内存临时资源,销毁物体不会自动释放材质内存,容易造成内存泄漏。

内存/GC重点(面试高频)

  1. 每调用一次renderer.material,不是每次都复制:只有第一次访问实例化;之后返回已有副本。
  2. 但是:如果你频繁在Update里写 var mat = renderer.material; 本身不会重复复制,但要注意逻辑。
  3. 内存泄漏坑:物体Destroy了,自动生成的material实例不会自动销毁,必须手动Destroy(mat)释放。
// 危险:物体销毁,mat还在内存
Material mat = renderer.material;
Destroy(renderer.gameObject); 
// mat仍然驻留内存,需要手动 Destroy(mat);

常见错误写法

❌错误1:运行时修改sharedMaterial

renderer.sharedMaterial.color = Color.red; 
// 会改工程原始材质,退出Play模式颜色不会复原!

❌错误2:每帧拿material做临时修改(逻辑没问题,但要注意实例生命周期)

void Update()
{
    // 第一次Update实例化,之后一直用这个副本;不会每帧复制材质
    var mat = rend.material;
    mat.color = ...;
}

✅正确模式

  1. 只想改当前物体:用renderer.material;物体销毁时记得销毁材质实例
  2. 只想读属性、不想产生实例副本:用renderer.sharedMaterial(只读!不要写)
  3. 需要全局统一修改所有物体:改材质资源预制体,不要运行时改sharedMaterial

补充:materials / sharedMaterials(多材质数组)

  • renderer.materials:返回材质实例数组,数组内每个材质都被实例化;修改只影响当前Renderer。
  • renderer.sharedMaterials:原始资源数组;修改数组元素会污染工程资源。

注意:materials每次调用会新建数组对象,产生GC!不要在Update反复调用.materials。

// ❌Update中,每次返回新数组,产生GC Alloc
foreach(var m in rend.materials){}

// ✅缓存一次数组
Material[] mats = rend.materials;
foreach(var m in mats){}

面试速记卡片版

  1. sharedMaterial:指向原始资源,修改会污染工程材质,运行完不会复原;多物体共享。只读使用。
  2. material:首次访问自动Instantiate复制独立实例;修改仅作用当前物体;物体销毁材质实例不会自动释放,要手动Destroy防止内存泄漏。
  3. .materials每次返回新数组,Update频繁调用产生GC;优先缓存。
  4. 不要运行时对sharedMaterial做赋值修改;读属性可以用sharedMaterial。

对比表格

API指向对象修改影响内存风险
renderer.sharedMaterialProject原始材质资源所有使用该材质的物体;污染工程资源无额外实例内存;改资源很危险
renderer.material复制出来的独立材质实例仅当前Renderer物体物体销毁材质实例残留,内存泄漏,需要手动Destroy
renderer.sharedMaterials原始材质数组修改元素污染资源每次调用不新建数组
renderer.materials实例化后的材质数组仅当前物体每次调用生成新数组,产生GC

面试常问坑:
Q:我在Play模式修改material,停止运行材质复原;修改sharedMaterial停止运行修改还在,为什么?
A:material是运行时复制的临时实例;sharedMaterial直接操作磁盘上的资源文件。

Q:物体Destroy之后,material实例还在吗?
A:还在,Renderer销毁不会自动Destroy自动生成的Material实例,需要手动管理。


资料白嫖,技术互助

学习路线指引(点击解锁)知识定位人群定位
🧡 Unity系统学习专栏 入门级本专栏从Unity入门开始学习,快速达到Unity的入门水平
💛 Unity实战类项目 进阶级计划制作Unity的 100个实战案例!助你进入Unity世界,争取做最全的Unity原创博客大全。
❤️ 游戏制作专栏 难度偏高分享学习一些Unity成品的游戏Demo和其他语言的小游戏!
💚 游戏爱好者万人社区 互助/吹水数万人游戏爱好者社区,聊天互助,白嫖奖品
💙 Unity100个实用技能 Unity查漏补缺针对一些Unity中经常用到的一些小知识和技能进行学习介绍,核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺

在这里插入图片描述

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/zhangay1998/article/details/164450683

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--