Unity UIToolkit中Material为空,无法设置自定义属性求助
问题:Unity UIToolkit自定义着色器属性运行时无法修改
在Unity UIToolkit中使用带有自定义属性_RevealAmount的材质,UIBuilder中拖动调整该属性可正常实现图片水平显隐效果,但运行时通过C#代码修改MaterialDefinition的该属性完全无效,且打印Material对象为null。
原代码
public class MyUI : MonoBehaviour { private UIDocument ui; private void OnEnable() { ui = GetComponent<UIDocument>(); var root = ui.rootVisualElement; var renderTexture = root.Q<VisualElement>("renderTexture"); Debug.Log(renderTexture.style.unityMaterial.value.material); // 输出Null DOVirtual.Float(0f, 1f, 5f, v => { renderTexture.style.unityMaterial.value.SetFloat("_RevealAmount", v); // 无效果 //renderTexture.style.unityMaterial.value.SetFloat("RevealAmount", v); // 无效果 //Debug.Log("Reveal amount: " + v); // 正常输出0到1的往复值 }).SetLoops(-1, LoopType.Yoyo); } }
问题根源
UIToolkit的MaterialDefinition只是材质的引用定义,并非运行时实际实例化的Material对象。直接操作style.unityMaterial.value无法修改运行时的材质状态,因为它不指向实际的渲染材质实例。
解决办法
步骤说明
- 获取运行时材质实例:通过
MaterialDefinition.GetMaterialInstance()方法获取可修改的材质实例。 - 缓存实例避免重复获取:提升性能,减少不必要的实例创建。
- 修改属性后强制UI重绘:调用
VisualElement.MarkDirtyRepaint()触发UI重新渲染,让属性修改生效。
修改后的代码
public class MyUI : MonoBehaviour { private UIDocument ui; private Material targetMaterial; private void OnEnable() { ui = GetComponent<UIDocument>(); var root = ui.rootVisualElement; var renderTextureElement = root.Q<VisualElement>("renderTexture"); var materialDef = renderTextureElement.style.unityMaterial.value; if (materialDef != null) { targetMaterial = materialDef.GetMaterialInstance(); Debug.Log("获取到材质实例: " + targetMaterial); } if (targetMaterial != null) { DOVirtual.Float(0f, 1f, 5f, v => { targetMaterial.SetFloat("_RevealAmount", v); renderTextureElement.MarkDirtyRepaint(); // 强制UI重绘 }).SetLoops(-1, LoopType.Yoyo); } else { Debug.LogError("无法获取有效的材质实例"); } } private void OnDisable() { // 释放材质实例,避免内存泄漏 if (targetMaterial != null) { MaterialDefinition.ReleaseMaterialInstance(targetMaterial); targetMaterial = null; } } }
额外注意事项
- 确保
VisualElement的名称"renderTexture"与UIBuilder中的元素名称完全一致。 - 着色器中的属性名称必须为
_RevealAmount(带下划线),与代码中的调用严格对应。 - 在组件禁用时释放材质实例,避免不必要的内存占用。
内容的提问来源于stack exchange,提问作者Paulo Renan
相关产品推荐
相关产品推荐

