
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复制一份材质实例
- 首次访问:把
sharedMaterial复制一份独立Material实例给到渲染器; - 后续再读material,返回这个已经实例化好的副本;
- 修改material的颜色、Shader属性,只影响当前物体,其他物体不受影响;
- ⚠️运行时生成的材质实例属于内存临时资源,销毁物体不会自动释放材质内存,容易造成内存泄漏。
内存/GC重点(面试高频)
- 每调用一次
renderer.material,不是每次都复制:只有第一次访问实例化;之后返回已有副本。 - 但是:如果你频繁在Update里写
var mat = renderer.material;本身不会重复复制,但要注意逻辑。 - 内存泄漏坑:物体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 = ...;
}
✅正确模式
- 只想改当前物体:用
renderer.material;物体销毁时记得销毁材质实例 - 只想读属性、不想产生实例副本:用
renderer.sharedMaterial(只读!不要写) - 需要全局统一修改所有物体:改材质资源预制体,不要运行时改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){}
面试速记卡片版
- sharedMaterial:指向原始资源,修改会污染工程材质,运行完不会复原;多物体共享。只读使用。
- material:首次访问自动Instantiate复制独立实例;修改仅作用当前物体;物体销毁材质实例不会自动释放,要手动Destroy防止内存泄漏。
.materials每次返回新数组,Update频繁调用产生GC;优先缓存。- 不要运行时对sharedMaterial做赋值修改;读属性可以用sharedMaterial。
对比表格
| API | 指向对象 | 修改影响 | 内存风险 |
|---|---|---|---|
| renderer.sharedMaterial | Project原始材质资源 | 所有使用该材质的物体;污染工程资源 | 无额外实例内存;改资源很危险 |
| 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




