Godot: get_surface_material

Created on 22 Aug 2019  路  9Comments  路  Source: godotengine/godot

Godot version:
Version 3.1.1 official

OS/device including version:
windows 10

Issue description:
Steps to reproduce:
I create a cube, uvw map it, create texture, import it to godot.
I create a new inherited scene from the exported dae file, The texture is applied correctly and shows up in the material. The problem is with accessing it from code.
I put a script in MeshInstance like this
extends MeshInstance

export(Texture) var box_texture

func _ready():
print(get_surface_material_count())
print(get_surface_material(0))
var new_material = SpatialMaterial.new()
new_material.albedo_texture = box_texture
set_surface_material(0, new_material)
print(get_surface_material_count())
print(get_surface_material(0))

The result is like this:
* Debug Process Started *
OpenGL ES 3.0 Renderer: GeForce GTX 970M/PCIe/SSE2
1
[Object:null]
1
[SpatialMaterial:1146]

As you can see, even if the get_surface_material_count() sees the material, while getting the material using get_surface_material returns null object. On the other hand if I create a material on code and run the same print statements again, it shows correct SpatialMaterial.

Minimal reproduction project:
https://github.com/roiteee/godot_issue_surface_material

documentation enhancement core editor

Most helpful comment

@Lexpartizan I agree the naming is confusing. For 4.0 I would like to rename $MeshInstance.get_surface_material() to $MeshInstance.get_surface_override_material()

All 9 comments

I think this reflects an issue with how the editor assigns materials.

If you do surface_get_material(0) on the Mesh, it should work. E.g.

$MeshInstance.mesh.surface_get_material(0)

script on MeshInstance
var mat = mesh.surface_get_material(0) #协褌芯褌 谐谢褞泻 械褋褌褜 薪邪 谐懈褌褏邪斜械!
print (mat)

Null
Still not working in 3.2 stable

Do you have your material assigned to the MeshInstance or to the Mesh?

Mesh.surface_get_material() returns the material assigned to a particular surface, while MeshInstance.get_surface_material() returns the surface material override.

To clarify what is going on here. It is not a bug. Below is a sample layout of a Mesh with 2 surfaces.

MeshInstance
|
-- Mesh
--|
---- Surface0
--|
---- Surface1

Materials can be assigned at different places. You can assign the material to the surfaces individually, you can assign a material override in the MeshInstance, or you can assign a per-surface material override in the MeshInstance

With Materials the above layout becomes

MeshInstance
| Material override (overrides all materials on all surfaces)
| Material0 (overrides Surface0 Material)
| Material1 (overrides Surface1 Material)
-- Mesh
--|
---- Surface0
----| Material
--|
---- Surface1
----| Material

The OP's issue is that they have assigned a material to "Surface0 Material" But then they are using MeshInstance.get_surface_material(0) which returns "Material0" which is rightly null

@lexpartizan I am guessing you have done the opposite. It sounds like you have assigned a material to "Material0" but are using Mesh.surface_get_material(0) which is returning "Surface0 Material" which is null

Can't this be unified somehow (potentially with a new function) so that it gets the override or mesh material, whichever exists?

@Zireael07 Thats a good idea. Something like MeshInstance.get_active_material()

Big Thanks!
The fact is that these methods are called very similar, but they are written a little differently.
MeshInstance.get_surface_material(0)
mesh.surface_get_material(0)
In the first case, the "get" is at the beginning, in the second in the middle.

I didn't notice this difference. And when just call Meshinstance this method, I thought that it does not exist.

@Lexpartizan I agree the naming is confusing. For 4.0 I would like to rename $MeshInstance.get_surface_material() to $MeshInstance.get_surface_override_material()

that would still have get at the beginning of 1 and the middle of the other. Instead of calling it get_active_material(), why not call it get_material()? Surely it isn't a stretch to infer that one wants the active one.

Was this page helpful?
0 / 5 - 0 ratings