Search code examples
c#unity-game-enginedumpshaderlab

Dump resources from Unity game to a file


I am trying to create a function that dumps every Resources data in a Unity game to a file and was able to dump the video, audio, script names and the image on the screen from the current loaded scene.

I am stuck when trying to do the-same thing for the shader data such as Textures and Matrix, Vectors and int values and floats. I know I can obtain these formation with the Material.GetXXX functions.

For example, I can currently obtain the main Texture from the standard shader which has a Texture type property named _MainTex with:

Material mat = gameObject.GetComponent<MeshRenderer>().material;
Texture mat1Tex = mat.GetTexture("_MainTex");
SaveTex(mat1Tex);

The problem is that I need to know the names of properties and which type it is such as Texture, Matrix, Float, Color and so on before I can obtain their values during run-time

I expect many shaders from third party sources to be in the project and it would be complicated to manually go over each shader, copy their property names and the type so that I can obtain the data.

Is there a way to get the shader property and the type required to retrieve their values with the Material.GetXXX functions? If this is not possible, is there any way to dump the shader data individually?

Note:

This is not a save feature and I'm not looking for way to save and load game state. It's a plugin used to analyze and troubleshoot Unity games.


Solution

  • Use ShaderUtil.

    • ShaderUtil.GetPropertyCount will let you iterate through each property.

    • ShaderUtil.GetPropertyName will let you get the property name for use in methods like GetTexture.

    • ShaderUtil.GetPropertyType will let you call the proper methods to handle the property you are currently on.

    For example:

    Shader shader = mat.shader;
    for (int i = 0 ; i < ShaderUtil.GetPropertyCount(shader) ; i++) {
        String propertyName = ShaderUtil.GetPropertyName(shader,i);
        ShaderUtil.ShaderPropertyType propertyType = ShaderUtil.GetPropertyType(shader,i);
    
        switch(propertyType) {
            case ShaderUtil.ShaderPropertyType.TexEnv: {
                Texture tex = mat.GetTexture(propertyName);
                SaveTex(tex);
            } break;
    
            default: {
                Debug.Log(propertyName + " is not a texture.");
            } break;
        }
    }
    

    It's from the UnityEditor namespace which means that it can only be used in the Editor. It's still fine. You just have to detect when the build button is clicked then obtain the properties and types with ShaderUtil then save to the resources folder like this.