Hey
For my character creator i need all my characters to use different textures.
For example, i create an empty Texture2D and apply over it the skin and clothes and apply the texture to a Material that is exclusive to that character, but the Material constructor is obsolete…
Are there any alternatives to this?
“new Material(oldMaterial)” will create a copy of a material named “oldMaterial” at runtime. Changes made to that copy will not affect the original.
Also, if you have any kind of renderer (MeshRenderer, CanvasRenderer, TrailRenderer, etc.) you can call “renderer.material.SetTexture(…)” and the change will only apply to that renderer, not every object with that material.
You can also create a new material by passing it a shader reference. Here is some sample code from a project of mine. You probably won’t be able to use my code directly, because I used Shader Sandwich (from the Asset Store) to make a custom shader with properties I needed in my application. But this shows you the basic logic. The comment lines are an adaptation from an example in the Unity scripting manual, which I tweaked to get “almost” what I wanted from the Standard shader. (It was still not exactly right, which is why I made my own later.)
public static Material MakeSimpleMaterial() {
Shader shader;
//shader = Shader.Find("Standard");
shader = Shader.Find("CustomShader01");
Material mat = new Material(shader);
//mat.EnableKeyword("_ALPHAPREMULTIPLY_ON");
mat.hideFlags = HideFlags.HideAndDontSave;
//mat.SetInt ("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
//mat.SetInt ("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
//mat.SetInt ("_Cull", (int)UnityEngine.Rendering.CullMode.Front);
//mat.SetInt ("_ZWrite", 1);
//mat.SetInt ("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Disabled);
mat.SetColor("_Color", Color.red);
return mat;
}
I know this isn’t an “out of the box” solution for you, but hopefully it will be informative in a general way.
Thanks guys!
Gambit’s solution worked perfectly for me, but for syscrusher one, i don’t know if i should use it since the Material constructor is going to get deleted from newer versions of Unity. I would love to be able to use it, since it allows more freedom when creating custom textures.
Can you use the existing Material on the Renderer? If the Material is being shared among many Renderers, accessing GetComponent().material will create a copy of the material for that specific renderer if the material is already shared. If the Renderer is the only one using that material then it will reuse the same material.
You saved my life! Thanks a lot!
Oh and one more question, so with this i can get the Renderer material, apply a texture over it and then use it on all the other Renderers associated with the same Character so all the body parts use the same material, right? And i will have only 2 copies of the material(The original and the duplicated one)?
Yes, you should be able to assign the new material out to other renderers and share it.
You should also be aware of Renderer.sharedMaterial, which will edit the original material and thus affect all renderers already using that material.
[quote=“Nahuel3d, post:7, topic: 629789, username:Nahuel3d”]
Oh and one more question, so with this i can get the Renderer material, apply a texture over it and then use it on all the other Renderers associated with the same Character so all the body parts use the same material, right? And i will have only 2 copies of the material(The original and the duplicated one)?
[/quote]Ah, one thing I would need to check is if assigning to Renderer.material creates a second Material copy, then modifying the first Material copy might not affect that Renderer anymore.
Oh, that’s just what i want to do:
Use Renderer.Material one time to duplicate the material and apply it to all the meshes and then use Renderer.sharedMaterial to modify the duplicated one, and not the original
I’m not sure that is entirely correct. Here is the comment from the Scripting Reference: “Creating materials from shader source string will be removed in the future. Use Shader assets instead.” My method passes a Shader asset, not a source string.
Comments, anyone?
EDIT: The comment has changed in the 5.4 beta, so I posted a new thread on the beta forum asking for clarification of the docs.
EDIT 2: Another relevant thread suggests there was once a constructor that actually did have a shader source string as its parm. If so, then my constructor method is probably in the clear.
EDIT 3: Background on the likely reasons for the change, again suggesting Material(Shader…) is still supported.