IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity 一键制作预制体,一键修改预制体 -> 正文阅读

[游戏开发]Unity 一键制作预制体,一键修改预制体

?生成 、修改预制体属性 所用到的API

PrefabUtility.SaveAsPrefabAsset(GameObject instanceRoot, string assetPath);

PrefabUtility.SavePrefabAsset(GameObject asset);

AssetDatabase.LoadAssetAtPath(string assetPath, Type type);

AssetDatabase.SaveAssets();

AssetDatabase.Refresh();

具体用法:

一、制作预制体

获取预制体所需源文件路径(源文件最好放在Resources文件夹内方便加载,等制作完成后可以移动到合适位置)

主要方法:

1)、获取路径下的所有文件夹

        /// <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;
            }


        }

2)、获取文件下的文件

        /// <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;
            }

        }

3)、实践:

? 导入需要制作预制体的源文件,查看文件结构

? ? 新建Editor 文件夹 并创建脚本 MakePrefab

?

public class MakePrefab : EditorWindow
{

    [MenuItem("Tools/MakePrefab")]
    public static void CreatePrefabWindow()
    {
        EditorWindow window = EditorWindow.GetWindowWithRect(typeof(MakePrefab), new Rect(Screen.width / 3, Screen.height / 3, 800, 500), true, "MakePrefab");
        window.Show();
    }
}

绘制面板

 private static string toSavePrefabPath = "Assets/Entities";


    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 级结构
        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];

                        PrefabUtility.SaveAsPrefabAsset(go, $"{toSavePrefabPath}/{modeName}.prefab");
                        DestroyImmediate(go);
                    }
                    AssetDatabase.Refresh();
                }
            }

        }

    }

效果展示

二、修改预制体:

当预制体中的某个属性设置错误的时候,比如 IsKinematic 属性时,需要统一修改这个属性

    /// <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);
        }
        //修改属性
        for (int i = 0; i < prefabs.Count; i++)
        {
            if (prefabs[i].transform.childCount > 0 && prefabs[i].transform.GetChild(0) != null)
            {
                if (prefabs[i].GetComponent<Rigidbody>() != null)
                {
                    prefabs[i].GetComponent<Rigidbody>().isKinematic = false;                 
                    PrefabUtility.SavePrefabAsset(prefabs[i]);                  
                }              
            }          
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

效果展示

?

?这样所有的预制体都已经制作完成啦,以及后续修改里面的属性!

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 23:17:42  更:2022-07-04 23:18:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:27:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码