NGUI Material Shader SetFloat 不起作用
通常情况下,我们在Unity3d种可以通过material.SetFloat(name, xxx) 修改参数来达到我们的Material[Shader]的效果.
但是在 NGUI 的UITexture中,除了初始化时调用可以生效之外, 在Update或其他地方修改参数均不起效.
其原因是 NGUI 已经将calldraw作了缓存(没细查),我们可以在设置后调用 RemoveFromPanel 和 SetDirty 来进行重建:
实例:
void SetFloat(UITexture t, string name, float v) { var m = t.material; m.SetFloat(name, v); t.RemoveFromPanel(); t.SetDirty(); }
当然这会导致 Panel重建,慎用.
更新:这个问题真的是误人子弟了... 以下更新下正常的使用方法:
public UITexture tex; void Start(){ tex.onRender += mat =>{ mat.SetFloat("key", 0.5f); }; }
首先得明白NGUI 的原理, NGUI 因为图片与图片之间通过 设置 Depth 来确定图片的绘制顺序,并不能单纯使用z轴来设定.
所以NGUI内部有自己渲染排序方式.具体查看:
NGUI的流光shader解决方案
.以下为部分摘录
NGUI的onRender 大家可能会奇怪,上面的代码中的onRender什么鬼,我直接在脚本内部,起个定时器什么的来修改shader的参数不就行了吗。有兴趣的同学可以尝试一下,不管用的。 这个问题一开始我也遇到了,google一下,原来这和NGUI的渲染机制有关。大概解释一下:
NGUI在渲染的时候,大家都知道,会合并DrawCall,合并的必然是使用同一材质球的元素,NGUI内部会新建一个Material,然后UIDrawCall会进行一次渲染,渲染的时候就会调用onRender这个回调,并且把这个新建的Material传过来,方便我们做一些自定义的操作
看看UIWidget中的onRender定义大家也就都明白了:
/// <summary> /// Set the callback that will be triggered when the widget is being rendered (OnWillRenderObject). /// This is where you would set material properties and shader values. /// </summary> public UIDrawCall.OnRenderCallback onRender { ... }