Instantiate a prefab of a Blender model w/ Behavior that supports changes to model
(This is not a question, but an explanation of a solution to a problem I've been facing. I'm curious if this is the optimal way to solve what I expect to be a near ubiquitous need, namely...)
Goal
Be able to instantiate a Prefab programatically that has a RigidBody, possibly some behavior (e.g., an arrow in flight, a rock, an enemy) whose model was developed in Blender such that whenever the model is changed there is zero work required to update the project... just save in Blender, and click play and the game is using the new model.
Addressing the above goal has proven to be surprisingly difficult to do, so I wanted to post to make sure that I'm not missing something obvious, and share what I've found.
Solution
Create project folders "Resources/Blender" and "Resources/Prefabs".
Save Blender model in "Resources/Blender".
Tweak Materials of imported object in Unity since loader doesn't do this automatically.
Create an Empty Object, and attach RigidBody, behaviors etc (but not the model), Reset transform etc.
Create Prefab from the Empty Object into "Resources/Prefabs", and give it a similar name to the model.
With that done, to create the object at runtime, "Instantiate" by name each part, and then make the "EmptyObject" version the parent of the model, reposition etc. Arrows fly, objects get dropped, monsters spawn. When the model is updated in blender, just save and play, and even the materials stay applied (though unsure why that works so well).
C# sample:
GameObject obj = (GameObject)Instantiate(Resources.Load("Prefabs/arrow"));
GameObject arrowBlend = (GameObject)Instantiate(Resources.Load("Blender/arrow"));
arrowBlend.transform.parent = obj.transform; // linked!
Rigidbody arrowRigid = obj.GetComponent<Rigidbody>();
Vector3 startOffset = transform.rotation * new Vector3(0, 0, 1.5f);
arrowRigid.position = transform.position + startOffset;
// etc...
I recommend preloading the Resources and storing references etc.
Comments
Given how frequently dynamic objects are used in games, I'm surprised with how much effort it was to get this setup in a stable, reimportable way. I'm hoping there is something obvious I missed in Unity. I tried a number of different thing like creating a prefab of my model, but that seems to fix the model at the time of prefabing, rather than have a prefab that links to the model's name (prefab of a prefab is a no go).
Also, putting all the runtime addressable entities into "Resources" folder seems quirky. Perhaps there are projects out there with large numbers of objects that don't get built into the game, but in my game that won't be the case. Many programming languages cull unreferenced compiled code at link time, but support an "alwayslink" pragma or equivalent; maybe Unity could use a bool flag on each project entities so to force it to be addressable?
I'm having a lot of fun teaching my kids about programming, games, and modelling w/ Unity. Thanks all!
JJ
Your answer
Follow this Question
Related Questions
How to fix this cube ? 1 Answer
Imported Models Not Rendering Correctly? 5 Answers
Normal map seams 0 Answers
Blender to Unity armature not in correct place... 1 Answer
Can faces be made visable from both sides on assets from blender. 1 Answer