我正在编写一个脚本,当悬停在上面时,它会改变选定对象的材料。这个物体(S)有多种材料附在一起。问题是,只有第一种材料正在改变,而其他材料则保持不变。当射线击中适用的物体时,它会改变颜色,当光线不再在物体上时,它就会改变回默认的颜色。我使用的是资产商店的SNAPS原型资产,不能编辑它们来使用一种材料,我也想不出如何让它们使用一种材料,如果有更简单的方法可以这样做,请告诉我。
下面是我尝试过的代码:
void Update()
{
if (_selection != null)
{
var selectionRenderer = _selection.GetComponent<Renderer>();
Material[] materials = selectionRenderer.materials;
foreach (Material mat in materials)
{
selectionRenderer.material = defaultMaterial;
}
_selection = null;
}
camera = Camera.main;
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
var selection = hit.transform;
if (selection.CompareTag(selectableTag))
{
var selectionRenderer = selection.GetComponent<Renderer>();
Material[] materials = selection.GetComponent<Renderer>().materials;
if (selectionRenderer != null)
{
foreach (Material mat in materials)
{
selectionRenderer.material = highlightMaterial;
}
_selection = selection;
}
}
}
}
发布于 2021-06-14 04:53:55
你所做的是正确的是,你正在使用GetComponent<Renderer>().materials
来获取所有的材料。但你做错的是,然后你用selectionRenderer.material = highlightMaterial
设置材料。这一行使用渲染器的material
属性,它总是只引用第一个材料。
为了更改对象上的每个材料,您需要替换整个.materials
数组。
然而,很可能有更好的方法来做你想要做的事情。不鼓励通过这些属性访问渲染器的材料,因为每当您这样做时,就会在内存中创建一个全新的材料。新的材料不会与任何东西共享,所以你会强迫GPU做更多的抽奖电话。
临时更改对象呈现方式的更好方法是使用材料性能块。这些允许您覆盖一个或多个材料的个别设置,而无需切换渲染器实际使用的材料。例如,当您想要将一堆渲染器上的所有材料的发射颜色更改为黄色时:
foreach(var renderer in GetComponentsInChildren<Renderer>) {
var propertyBlock = renderer.GetPropertyBlock();
propertyBlock.SetColor("Emission", Color.yellow);
renderer.SetPropertyBlock(propertyBlock);
}
注意:属性名称是按比例输入的。什么名字是可用的,他们做什么取决于着色器。很有可能,您的特定着色器的发射属性不是所谓的“发射”,而是其他的东西。
https://gamedev.stackexchange.com/questions/194070
复制