Last active
June 19, 2024 07:58
-
-
Save andreiagmu/b60452981058564fc5454f7e46940113 to your computer and use it in GitHub Desktop.
Loads all 3D models from a folder and saves them as prefabs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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