I have a ~200 imported models (as fbx from Blender). Each one has a standard base texture and normal map.
By default, Unity appears to have a placeholder material called “None” for each imported fbx, but it is not shown as a separate material (in the file explorer). I’m using URP and the Shader is auto-set to URP/Lit.
Now, I have a Shader Graph version of URP/Lit, and I’ve added some additional effects I can turn on/off.
I want these effects to be available to all my imported models.
All I would need to do is change the Shader of this elusive “None (Material)”. However, I’m worried there’s no quick fix…
What is the best way to handle this given that ALL PREFABS ARE GENERATED AT RUNTIME?
The Easiest option would be auto-setting to my custom shader instead of URP/Lit. Is there a setting somewhere to do this?
Should I create just one material with no textures and set the textures and FX settings at runtime? The drawback here is that the prefab’s textures will be blank for editor/prefab editor use.
Should Each Imported Model Have its own dedicated material?
Prefabs cannot be generated at runtime. Prefabs exist only in editor and are created only by tooling in the UnityEditor namespace, which never goes into a final build, ever.
You can disable this by not importing materials at all. This lets you create and apply any material you like to any geometry.
Here are my notes on using Blender3D with Unity3D:
When I work in Blender3D for Unity3D use, I follow these organizational rules:
use Empty Blender Objects as folders: they come out as an extra GameObject
ALWAYS parent everything to a single Empty, even a single object
ALWAYS apply all Scales and Rotations on every Transform throughout your hierarchy.
put as few objects in a given .blend file as possible, combining them in Unity into a prefab
REMOVE unnecessary items (Light, Camera, etc.)
use good names for your Blender3D objects and NEVER RENAME them after Unity sees them
don’t even think about final Materials or Textures in Blender. Set the mesh to use N different materials, but always set up the materials within Unity and disregard what gets imported.
Costs of using Blender files directly vs exporting to FBX:
Unity imports Blender3D objects as FBX via a little Python script:
The Python script that Unity uses (substitute your Unity version number or search) to import:
What’s the proper way to phrase it, instantiated at runtime? What I meant was these meshes do not exist in the scene beforehand.
Thank you for the in-depth response. From here, I’m just wondering if I have to create a bunch of materials to replace the default “None” material since I only need to change the shader.
Procedural generation… yes, a subject near and dear to my heart.
It’s all about WHAT you instantiate. If you are only instantiating models you also need to do lots of other things like putting colliders or scripts or materials, etc. Yes, you CAN write code for that stuff but it’s probably the hardest most annoying code to write ever.
Instead, make prefabs in the editor, save them and instantiate and customize those prefabs at runtime. That lets you “capture” a bunch of work value into the prefabs, then instantiate and customize them.
If you want random samples of various procgen, you’re welcome to look around my MakeGeo project.
Thank you once again for the extra info/context. However, in order to close out this topic, what should I do with my material situation? Make a new material for each prefab so I can set the Shader?
I’m assuming I screwed myself with the None Material when I first imported the fbx’s.
Before you thunder too much further ahead, review how Materials are instanced for things in scene.
By default if you instantiate a prefab, it uses the Materials originally connected to it.
If you need to modify the Materials at runtime, how you get that material from the renderer determines if it will be the one on disk (which you should NOT modify at runtime), or a copy.
When you read a Material from a Renderer.material, Unity makes a copy of it when you modify it, making it necessary to assign it back.
If you use the Renderer.sharedMaterial field it does not make a copy.
You can always make fresh copies of your Materials before you modify them.
Play with it antagonistically a bit, you’ll soon see how it works.