Skip to content

Instantly share code, notes, and snippets.

@andreiagmu
Last active May 30, 2020 02:49
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andreiagmu/b60452981058564fc5454f7e46940113 to your computer and use it in GitHub Desktop.
Save andreiagmu/b60452981058564fc5454f7e46940113 to your computer and use it in GitHub Desktop.
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