material和sharedMaterial

Unity3D中,Renderer组件有两个属性:material和sharedMaterial,它们都可以用来获取Renderer的材质属性。但是它们之间却又很大的区别,下面通过示例来讲解一下。

准备工作:unity3d中新建一个空场景;创建两个cube,分别命名为Cube0、Cube1;在Project中新建一个材质球,取名M0,shader选择Unlit/Color,shader的Main Color属性设为白色,即(255,255,255,255);将M0分别赋值给Cube0、Cube1;新建一个脚本TestMaterial,将脚本拖到Cube0上。如下所示:

1、测试material

TestMaterial脚本的内容如下所示:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class TestMaterial : MonoBehaviour
 5 {
 6     Renderer thisRenderer;
 7     // Use this for initialization
 8     void Start()
 9     {
10         thisRenderer = GetComponent<Renderer>();
11         thisRenderer.material.color = Color.red;
12     }
13 }

运行,效果如下图所示:

注意,只有Cube0的颜色改变,在mesh renderer中,材质球的名字是M0(Instance)。

2、测试sharedMaterial

代码如下:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class TestMaterial : MonoBehaviour
 5 {
 6     Renderer thisRenderer;
 7     // Use this for initialization
 8     void Start()
 9     {
10         thisRenderer = GetComponent<Renderer>();
11         thisRenderer.sharedMaterial.color = Color.red;
12     }
13 }

运行,效果如下所示:

注意,Cube0、Cube1的颜色均发生改变,但是在mesh renderer中,材质球的名字还是M0。但是,此时在Project中的M0的Main Color属性发生了改变,如下所示:

 

总结:使用material属性的时候,每次都会new一份新的material作用与它,但不会改变本地工程中的材质material;sharedMaterial是共享材质,无论使用多少次,内存中都只会占用一份内存,但是会影响其他使用同一材质球的对象。所以,从效率上来说,sharedMaterial的效率更高。

 

重点来了:在实际使用的时候,我们可以在开始的时候使用material产生一个新的材质球作用于该renderer,然后之后的操作都使用sharedMaterial,这样,效率更高,而且不会影响其他使用同一个材质球的renderer。

最后,附上示例代码:


 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class TestMaterial : MonoBehaviour
 5 {
 6     Renderer thisRenderer;
 7     float delay = 3f;
 8     float changeColorTm;
 9     bool isChangeOnce;
10 
11     void Awake()
12     {
13         thisRenderer = GetComponent<Renderer>();
14         thisRenderer.material.color = Color.red;
15         changeColorTm = Time.time + delay;
16         isChangeOnce = false;
17     }
18 
19     void Update()
20     {
21         if (!isChangeOnce && Time.time >= changeColorTm)
22         {
23             isChangeOnce = true;
24             thisRenderer.sharedMaterial.color = Color.green;
25         }
26     }
27 }

 

总结

当使用Renderer.material的时候,每次调用都会生成一个新的material到内存中去,这在销毁物体的时候需要我们手动去销毁该material,否则会一直存在内存中。
也可以在场景替换的时候使用Resources.UnloadUnusedAssets去统一释放内存。

当使用Renderer.sharedMaterial的时候并不会生成新的material,而是直接在原material上修改,并且修改后的设置就会被保存到项目工程中。一般不推荐使用这个去修改,当某个材质球只被一个gameobject使用的时候可以使用这个去修改,并且最好在修改之前把原属性设置保存,当使用完毕后立即恢复原设置,防止下次加载后的gameobject上还会残留之前的设置信息。

如果是主角这一类gameobject身上需要修改材质的属性或者shader属性比较多的时候,可以第一次使用material,这样可以动态的生成一个material实例,然后再使用sharedmaterial,动态的修改这个新生成的material,而且不会创建新的material。


 ______________________________________________________________________________________

// 摘要:
         //     Returns the first instantiated [[Material]] assigned to the renderer.
//返回第一个实例化的Material指定给renderer
         public  Material  material {  get ;  set ; }
// 摘要:
         //     The shared material of this object.
//直接返回这个object的material
         public  Material  sharedMaterial {  get ;  set ; }

假如两个prefab公用同一个material,prefabA和prefabB,如果要获取prefabA中的material,prefabA. GetComponent< MeshRenderer >().material,此时prefabA中的material会被Instantitated在赋给prefabA,即此时prefabA是一个新的material,做任何更改不会影响原来的material,当然也不会影响到prefabB中的material。
但是如果是获取prefabA的sharedMaterial,则返回的是这个material本身,如果做任何修改,则material发生变化,同时,应用该material的其他prefab也会发生变化。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值