3

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.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • 3
    I can't be the only one amazed that there's something you don't know about Unity. Feel like this deserves a screenshot, or framing, or an achievement unlocked award... or something ;) – Confused Nov 01 '18 at 01:43
  • 1
    Surprised you're amazed. No one knows everything. and all learn from others on this site. – Programmer Nov 01 '18 at 01:51
  • No. I'm AMAZED! I have a pedestal in my computer room. Upon which your icon sits. It says: God-like Unity User, right underneath ;) – Confused Nov 01 '18 at 01:52
  • @Confused Lol thanks – Programmer Nov 01 '18 at 01:53

1 Answers1

5

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.

Ruzihm
  • 19,749
  • 5
  • 36
  • 48
  • 1
    Being using Unity for a long time and have never came across about this API. This will do the job. I just checked it out and it looks like 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](https://stackoverflow.com/a/52892856/3785314). It would be good to mention that in your answer. Thanks. – Programmer Oct 31 '18 at 18:09
  • 1
    Ah, I've never used it before. That's a good thing to add. I'm just going to add that part of your comment to the answer verbatim if that's ok. – Ruzihm Oct 31 '18 at 18:13
  • 1
    That's fine with me – Programmer Oct 31 '18 at 18:13