I’m trying to understand inheritance, specifically involving resources. I can across this and am confused by it:
var texture: Texture2D = $MeshInstance3D. get_active_material().albedo_texture
Why does this work? get_active_material() is a method of MeshInstance3D that returns a Material. albedo_texture is a property of BaseMaterial3D. Material does not inherit from BaseMaterial3D, rather it’s the other way around. Material inherits from Resource. So what am I missing here?
The returned material happens to be a BaseMaterial3D/StandardMaterial3D, Godot doesn’t have (very) strict typing, though you could set a warning for “unsafe property access”
No, the property is not guaranteed to work at run time.
There’s a “safe line” indecator in Godot that’s easy to miss, when the line number is green it’s considered type safe, your example would not be type safe as the active material could be a ShaderMaterial.
You can check the type before using inherited properties! as will cast, if it fails (i.e the supplied variable is not the correct or derived type) it will return null, or is which returns a bool if the type is correct or derived type
var material: Material = $MeshInstance3D.get_active_material()
# Checking with if
if material is BaseMaterial3D:
print("Is a base material or StandardMaterial3D!")
# Using as
var standard_material := material as StandardMaterial3D
# though you should probably still check !=null
if standard_material:
print("is a standard material, so it's texture is: ", standard_material.albedo_texture)
I think using as is the only way to get those sweet sweet green lines, but is will produce correct auto-complete