Loads all 3D models from a folder and saves them as prefabs.
// Model to Prefab Batch Converter for Unity | |
// Loads all 3D models from a folder and saves them as prefabs. | |
// by Andy Miira (Andrei Müller), October 2019 | |
// | |
// | |
// [INSTRUCTIONS] | |
// 0) Add this script inside an "Editor" folder in your project. | |
// You must create this folder if it doesn't already exist. | |
// | |
// 1) Open Unity, then click on | |
// "Tools -> Mirror Mirai -> Model to Prefab Batch Converter" at the menu bar. | |
// | |
// 2) Type or paste the paths for the Models Folder (where the source models are located) | |
// and Prefabs Folder (where the resulting prefabs will be saved). | |
// | |
// For example, if your models are located at Assets/Art/Models, you can use the paths: | |
// Models Folder: Assets/Art/Models | |
// Prefabs Folder: Assets/Art/Prefabs (if this folder doesn't exist, it will be created) | |
// | |
// TIP: In Unity's Project tab, you can left-click on a folder to select it, | |
// then right-click on it and select the option "Copy Path". | |
// After that, you can paste the path directly in the converter's Folder fields. | |
// | |
// 3) You can optionally add Colliders and Rigidbodies to the generated prefabs, by selecting the respective options. | |
// | |
// 4) Finally, click on the "Create Prefabs" button. | |
// The prefabs will be saved at the defined Prefabs Folder. | |
// | |
// | |
// Check out more Unity scripts and utilities at: | |
// https://gist.github.com/andreiagmu | |
using System.IO; | |
using UnityEditor; | |
using UnityEngine; | |
namespace MirrorMirai | |
{ | |
public class ModelToPrefabBatchConverter : ScriptableWizard | |
{ | |
public enum ColliderType | |
{ | |
None, | |
SphereCollider, | |
CapsuleCollider, | |
BoxCollider, | |
MeshCollider | |
} | |
public string modelsFolder; | |
public string prefabsFolder; | |
public ColliderType addCollider; | |
public bool convexMeshCollider; | |
public bool addRigidbody; | |
public bool kinematicRigidbody; | |
[MenuItem("Tools/Mirror Mirai/Model to Prefab Batch Converter")] | |
static void CreateWizard() | |
{ | |
DisplayWizard<ModelToPrefabBatchConverter>("Model to Prefab Batch Converter", "Create Prefabs"); | |
} | |
void OnWizardCreate() | |
{ | |
if (string.IsNullOrWhiteSpace(modelsFolder) || !Directory.Exists(modelsFolder)) { | |
Debug.LogWarning("modelsFolder not set to a valid directory!"); | |
return; | |
} | |
if (string.IsNullOrWhiteSpace(prefabsFolder)) { | |
Debug.LogWarning("You didn't set the prefabsFolder path!"); | |
return; | |
} | |
if (!Directory.Exists(prefabsFolder)) { | |
Directory.CreateDirectory(prefabsFolder); | |
} | |
DirectoryInfo dir = new DirectoryInfo(modelsFolder); | |
foreach (var fileInfo in dir.GetFiles()) { | |
if (fileInfo.Name.EndsWith(".fbx")) { | |
var filename = Path.GetFileNameWithoutExtension(fileInfo.Name); | |
var modelRootGO = (GameObject)AssetDatabase.LoadMainAssetAtPath(modelsFolder + "/" + fileInfo.Name); | |
var instanceRoot = (GameObject)PrefabUtility.InstantiatePrefab(modelRootGO); | |
ResetTransform(instanceRoot.transform); | |
if (addRigidbody) { | |
var rigidbody = instanceRoot.AddComponent<Rigidbody>(); | |
rigidbody.isKinematic = kinematicRigidbody; | |
} | |
if (addCollider == ColliderType.SphereCollider) { | |
var collider = instanceRoot.AddComponent<SphereCollider>(); | |
var totalBounds = TotalBounds(instanceRoot.transform); | |
collider.center = totalBounds.center; | |
collider.radius = Vector3.Distance(totalBounds.center, totalBounds.extents); | |
} | |
else if (addCollider == ColliderType.CapsuleCollider) { | |
var collider = instanceRoot.AddComponent<CapsuleCollider>(); | |
var totalBounds = TotalBounds(instanceRoot.transform); | |
collider.center = totalBounds.center; | |
collider.radius = Vector3.Distance(totalBounds.center, totalBounds.extents); | |
collider.height = totalBounds.size.y; | |
} | |
else if (addCollider == ColliderType.BoxCollider) { | |
var collider = instanceRoot.AddComponent<BoxCollider>(); | |
var totalBounds = TotalBounds(instanceRoot.transform); | |
collider.center = totalBounds.center; | |
collider.size = totalBounds.size; | |
} | |
else if (addCollider == ColliderType.MeshCollider) { | |
var objMeshes = instanceRoot.GetComponentsInChildren<MeshFilter>(); | |
foreach (var mesh in objMeshes) { | |
var collider = mesh.gameObject.AddComponent<MeshCollider>(); | |
collider.convex = convexMeshCollider; | |
} | |
} | |
PrefabUtility.SaveAsPrefabAsset(instanceRoot, prefabsFolder + "/" + filename + ".prefab"); | |
DestroyImmediate(instanceRoot); | |
} | |
} | |
} | |
void ResetTransform(Transform t) | |
{ | |
t.position = Vector3.zero; | |
t.rotation = Quaternion.identity; | |
t.localScale = Vector3.one; | |
} | |
Bounds TotalBounds(Transform root) | |
{ | |
Renderer[] renderers = root.GetComponentsInChildren<Renderer>(); | |
Bounds bounds = renderers[0].bounds; | |
for(int i = 1; i < renderers.Length; ++i) | |
{ | |
bounds.Encapsulate(renderers[i].bounds.min); | |
bounds.Encapsulate(renderers[i].bounds.max); | |
} | |
return bounds; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment