浅谈Unity之一键制作预制体

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
模型训练 PAI-DLC,5000CU*H 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
简介: 适用于制作多个预制体

前言:每日记录自己学习unity的心得和体会,小弟才疏学浅,如有错误的地方,欢迎大佬们指正,感谢~


1.模型先放到Resources文件夹下面方便读取,制作完预制体可以给他拖到其他文件夹

模型文件结构如下图(经测试放模型的文件夹名字要和模型名字一致,不然找不到,你也可以修改代码测试其他方法)


image.png

2.下面是编辑器脚本

using System.Collections;

using System.Collections.Generic;

using System.IO;

using System.Text.RegularExpressions;

using UnityEditor;

using UnityEngine;

/// <summary>

/// 编辑器脚本

/// </summary>

public class CreationPrefab : EditorWindow

{

   [MenuItem("Tools/一键生成Prefab")]

   public static void CreatePrefabWindow()

   {

       EditorWindow window = EditorWindow.GetWindowWithRect(typeof(CreationPrefab), new Rect(Screen.width / 3, Screen.height / 3, 800, 500), true, "CreationPrefab");

       window.Show();

   }

   //保存prefab的路径

   private static string toSavePrefabPath = "Assets/Prefabs/新模型库/机柜内设备";

   private void OnGUI()

   {

       EditorGUILayout.LabelField("预制体保存路径::", toSavePrefabPath, GUILayout.Width(110));

       toSavePrefabPath = EditorGUILayout.TextArea(toSavePrefabPath, GUILayout.Width(250));

       if (GUILayout.Button("转换预制体", GUILayout.Width(260)))

       {

           ToPrefab();

       }

       if (GUILayout.Button("修改预制体", GUILayout.Width(260)))

       {          

           ModifyPrefab(toSavePrefabPath);

       }

   }

   private void ToPrefab()

   {

       string path = "Assets/Resources";

       string[] allFolder1 = GetAllFolder(path);

       if (allFolder1 == null)

           return;

       //循环次数取决于 ,源文件的目录结构 ,此处为 4 级结构  

       //也就是Resources下面4级文件夹,到达模型文件夹  一级一个for循环

       for (int i = 0; i < allFolder1.Length; i++)

       {

           string path2 = $"{path}/{allFolder1[i]}";

           string[] allFolder2 = GetAllFolder(path2);

           if (allFolder2 == null)

           {

               return;

           }

           for (int j = 0; j < allFolder2.Length; j++)

           {

               string path3 = $"{path2}/{allFolder2[j]}";

               string[] allFolder3 = GetAllFolder(path3);

               if (allFolder3 == null)

                   return;

               for (int k = 0; k < allFolder3.Length; k++)

               {

                   string path4 = $"{path3}/{allFolder3[k]}";

                   string[] allFolder4 = GetAllFolder(path4);

                   Debug.Log($"编号:{k}     {allFolder3[k]}文件下有        {allFolder4.Length}       个文件夹!");

                   if (allFolder4 == null)

                       return;

                   if (!Directory.Exists(toSavePrefabPath))

                   {

                       Directory.CreateDirectory(toSavePrefabPath);

                   }

                   for (int l = 0; l < allFolder4.Length; l++)

                   {

                       string speedTree = $"{path4}/{allFolder4[l]}/{allFolder4[l]}";

                       string[] strs = Regex.Split(speedTree, path + "/", RegexOptions.IgnoreCase);

                       GameObject go = Instantiate(GetFileObj(strs[1]));

                       go.name = go.name.Replace("(Clone)", string.Empty);

                       //给预制体添加脚本,修改属性

                       //go.transform.tag = "Model";

                       //if (go.GetComponent<BoxCollider>() == null)

                       //    go.AddComponent<BoxCollider>();

                       //if (go.GetComponent<Rigidbody>() == null)

                       //    go.AddComponent<Rigidbody>();

                       //go.GetComponent<Rigidbody>().isKinematic = true;

                       string modeName = allFolder4[l].Split('_')[0];

                       for (int p = 0; p < go.transform.childCount; p++)

                       {

                           PrefabUtility.SaveAsPrefabAsset(go.transform.GetChild(p).gameObject, $"{toSavePrefabPath}/{go.transform.GetChild(p).name}.prefab");

                       }

                       DestroyImmediate(go);

                   }

                   AssetDatabase.Refresh();

               }

           }

       }

   }

   /// <summary>

   /// 获取路径下的 Obj

   /// </summary>

   /// <param name="path"></param>

   /// <returns></returns>

   private GameObject GetFileObj(string path)

   {

       GameObject go = Resources.Load<GameObject>(path);

       if (go != null)

       {

           return go;

       }

       else

       {

           Debug.Log(path);

           return null;

       }

   }

   /// <summary>

   /// 获取路径下的所有文件夹

   /// </summary>

   /// <param name="path"></param>

   /// <returns></returns>

   private string[] GetAllFolder(string path)

   {

       try

       {

           string[] dirs = Directory.GetDirectories(path, "*");

           string[] folderName = new string[dirs.Length];

           for (int i = 0; i < dirs.Length; i++)

           {

               string file = dirs[i].Split('\\')[1];

               folderName[i] = file;

           }

           return folderName;

       }

       catch (System.Exception)

       {

           return null;

       }

   }

   /// <summary>

   /// 修改预制体

   /// </summary>

   /// <param name="path"></param>

   private void ModifyPrefab(string path)

   {

     

       //获取文件下所有预制体文件

       DirectoryInfo info = new DirectoryInfo(path);

       FileInfo[] fileInfos = info.GetFiles("*.prefab");        

       List<GameObject> prefabs = new List<GameObject>();

       foreach (var item in fileInfos)

       {

           string paths = $"{path}/{item.Name}";

           GameObject prefab = AssetDatabase.LoadAssetAtPath(paths, typeof(GameObject)) as GameObject;

           prefabs.Add(prefab);

       }

       Debug.Log("执行么" + prefabs.Count);

       //修改属性

       for (int i = 0; i < prefabs.Count; i++)

       {            

           //修改预制体的position和旋转角度

           if (prefabs[i].GetComponent<Transform>() != null)

           {

               prefabs[i].GetComponent<Transform>().position = Vector3.zero;

               prefabs[i].GetComponent<Transform>().rotation = Quaternion.Euler(Vector3.zero);

           }

           //其他属性请自行添加即可

           //if (prefabs[i].GetComponent<Rigidbody>() != null)

           //{

           //    prefabs[i].GetComponent<Rigidbody>().isKinematic = false;

           //    PrefabUtility.SavePrefabAsset(prefabs[i]);

           //}

       }

       AssetDatabase.SaveAssets();

       AssetDatabase.Refresh();

   }

}

功能显示位置如下图

image.png

相关文章
|
5月前
|
图形学
【unity小技巧】手戳代码程序化绘制地形Terrain树和预制体物品、动物
【unity小技巧】手戳代码程序化绘制地形Terrain树和预制体物品、动物
49 0
|
6月前
|
C# 图形学
【Unity 3D】游戏对象、添加删除获取组件、预制体Prefabs简介
【Unity 3D】游戏对象、添加删除获取组件、预制体Prefabs简介
198 0
|
图形学 Android开发
Unity粒子特效系列-下雨预制体做好了,拿走直接就用!
众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣!!!
1824 1
|
图形学 Android开发
Unity粒子特效系列-龙卷风预制体做好了,unitypackage包直接用!
众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣!!!
2040 1
|
前端开发 图形学
只知道预制体是用来生成物体的?看我如何使用Unity生成UI预制体
本篇就介绍一下,如何使用UI的预制体,实例化预制体,以及在生成预制体的时候给预制体身上的UI属性就行设置。
|
vr&ar 图形学
【100个 Unity小知识点】☀️ | Unity 中的原始预制体 和 预制体变体 的区别和作用
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。 也可以简单把 Unity 理解为一个游戏引擎,可以用来专业制作游戏!
【100个 Unity小知识点】☀️ | Unity 中的原始预制体 和 预制体变体 的区别和作用
|
图形学
Unity 之 高版本预制体转低版本
高版本预制体(Prefab)转低版本,亲测版本Unity2019 --> Unity2017/Unity5.6
814 0
Unity 之 高版本预制体转低版本
Unity3dResources加载预制体与Sprite精灵图片
using UnityEngine; /// /// 加载预制体,必须放在Resources文件夹 /// public class AssetsGoblinWizard : MonoBehaviour { /// ///定义...
1975 0
|
图形学
Unity3D中的预制件(Prefab)的创建和使用说明!!!
首先我说明一下什么预制件? 在U3D里面我们叫它Prefab;我们可以这样理解:当制作好了游戏组件(场景中的任意一个gameobject),我们希望将它制作成一个组件模版,用于批量的套用工作,例如说场景中本质上“重复”的东西,“敌人”,“士兵”,“子弹”。