[Bug] Material doesn't have property _MainTex

ExqueezeMe

New member
The surface system seems to be causing some exceptions when the materials don't have a _MainTex property (using custom shaders). On SurfaceManager line 683 there is the check:
C#:
if (material.HasProperty(s_MainTextureID)) {
    return null;
}
But it seems to me that it should be the opposite (if the material doesn't have that property, return null), especially since the next line is
C#:
var texture = material.mainTexture;
which will always cause an exception at this point. Furthermore, it looks to me like line 491 should additionally check if
C#:
renderer.sharedMaterial.HasProperty(s_MainTextureID)
I'm not sure if there are additional places this is needed but that seems to have fixed the issue for me.
 
I need to take a closer look at this. From a pure logic point of view your changes make sense, but when I make those changes the correct effects don't spawn on the terrain outside of the demo scene.

Edit: It looks like there is a difference between material.GetTexture(s_MainTextureID) and material.mainTexture. When I shoot the terrain outside and do a get texture the former returns an error and the latter will return a value.
 
Last edited:
Hi Justin, I'm running into this problem, as well. I'm not using terrain in my game. I've written a custom shader for my ground meshes, and as a result I get this error, too. Any suggestions as to how best to proceed here? Should I just make the edits ExqueezeMe proposes?

Edit: Looks like the code in SurfaceManager.cs has changed a bit since ExqueezeMe encountered this error in June. s_MainTextureID no longer exists, so his proposed fix is no longer viable. Any help here would be greatly appreciated.

Thanks!
 
Last edited:
Update: My shader is built with Amplify Shader Editor. As a workaround, I changed the "Property Name" of one of my "Texture Sample" nodes to "_MainTex". After doing so, the error went away. Not ideal, but it worked.
 
Can you send me a repro scene so I can take a look? If you can only send the scene/shader that would be great - I already have the character controller :)
 
Can you send me a repro scene so I can take a look? If you can only send the scene/shader that would be great - I already have the character controller :)

I can't send you the scene, but you can download a copy of the shader here:

https://github.com/jasontuttle/Height-Blended-Material-Shader-for-Unity

That said, I changed the "Property Name" of one of my "Texture Sample" nodes to "_MainTex". After doing so, the error went away, and I'm fine with that solution, so no need to spend time on this if you don't want to.
 
I need to take a closer look at this. From a pure logic point of view your changes make sense, but when I make those changes the correct effects don't spawn on the terrain outside of the demo scene.

Edit: It looks like there is a difference between material.GetTexture(s_MainTextureID) and material.mainTexture. When I shoot the terrain outside and do a get texture the former returns an error and the latter will return a value.

Hey,

i run into the same problem with a shader not having _MainTex. I initially tried using material.GetTexture(s_MainTextureID) but after reading this i instead went ahead and changed my shader even though i would prefer not to as it is from an asset pack i bought. Did you found out why there is a difference between material.GetTexture(s_MainTextureID) and material.mainTexture for terrain?

Thanks!
 
Did you found out why there is a difference between material.GetTexture(s_MainTextureID) and material.mainTexture for terrain?
Unfortunately I never did. I am planning on integration with shader based assets such as Vegetation Studio Pro and CTS and when I do that I'll look into this again.
 
I'm running into a similar problem when using Unity with URP. Except the errors are: Material doesn't have a texture property '_BaseColor'

Material doesn't have a texture property '_BaseColor'
UnityEngine.Material:get_mainTexture()
Opsive.UltimateCharacterController.SurfaceSystem.SurfaceManager:GetMainTexture(Collider) (at Assets/Opsive/UltimateCharacterController/Scripts/SurfaceSystem/SurfaceManager.cs:489)
 
That looks related to mainTexture versus GetTexture() again. I'll take a closer look at it.
 
Top