Unity中使用代码将预制加载到场景

大家知道, 在日常修改预制的时候很方便, 我们将预制从资源文件夹往场景上"一拖", 然后就可以进行修改, 然后应用保存即可.

但是如果某些需求下, 我们想要使用代码来完成这个操作就比较麻烦.

比如需求为: 查找某个文件夹下所有预制, 如果其中有使用了RectMask2D组件的, 需要全部替换成Mask, 并且在替换完成后需要人工确定是否正确.

如果不需要人工确定, 其实很简单, 配合AssetDataBase相关的接口将预制加载出来, 然后替换组件后保存预制即可.

但是最后需要人工确定, 有问题还需要手动修改一部分, 那么就需要将预制加载到场景, 然后自动选中发生修改的节点来确定修改的正确.

按照正常的逻辑, 我可以像正常使用预制, 实例化对象的线路去思考, 但是实践下来发现, 加载到场景的是实例化之后的对象, 修改后无法应用保存, 和手动拖预制的结果不一致.

这时我们就需要使用另一个接口来达到目的了:

using UnityEditor;// 将给定场景中的给定预制件实例化
// 第一个参数target是预制资源
// 第二个参数destinationScene是目标场景, 如果不传就默认是当前场景
public static Object PrefabUtility.InstantiatePrefab (Object target , SceneManagement.Scene destinationScene);

首先需要遍历选中目录, 查找预制并加载:

// Selection.activeObject是当前选中的目录
var dir = AssetDatabase.GetAssetPath(Selection.activeObject);
if (!Directory.Exists(dir))
{Debug.LogError("选中的不是目录!" + dir);return;
}var allPrefabLst = AssetDatabase.FindAssets("t:Prefab", new []{dir});
foreach (var guid in allPrefabLst)
{var path = AssetDatabase.GUIDToAssetPath(guid);var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);var find = go.GetComponentInChildren<RectMask2D>(true);if (!find) continue;// ...
}

预制实例化并加到场景后, 将返回的对象转换类型后就可以设置其父节点:

var obj = PrefabUtility.InstantiatePrefab(prefab) as GameObject;// 注意第二个参数, 如果不为false, 会导致加载出来的对象transform发生变化
obj.transform.SetParent(rootTransform, false);

我们还需要找到当前场景中指定的节点作为其统一挂载的父节点:

// 比如: 场景中的节点层级为: rootNode/xxx/parent
// 通过调用GetCurSceneObject("rootNode", "xxx/parent")完成需求
static GameObject GetCurSceneObject(string rootName, string selectPath)
{var curScene = SceneManager.GetActiveScene();foreach (var rootGameObject in curScene.GetRootGameObjects()){if (!rootName.Equals(rootGameObject.name)) continue;var transform = rootGameObject.transform.Find(selectPath);if (transform) return transform.gameObject;}return null;
}

然后是替换组件:

private static void ReplaceRectMask2D(GameObject go)
{var children = rootGo.GetComponentsInChildren<RectMask2D>(true);foreach (var rectMask2D in children){var go = rectMask2D.gameObject;// 非运行模式下需要使用这个接口Object.DestroyImmediate(rectMask2D);go.AddComponent<Mask>();}
}

最后选中对象可以使用这里的介绍.

下面是完整的代码:

[MenuItem("Assets/PrintRectMask2DReferences", priority = 301)]
private static void PrintRectMask2DReferences()
{var dir = AssetDatabase.GetAssetPath(Selection.activeObject);if (!Directory.Exists(dir)){Debug.LogError("选中的不是目录!" + dir);return;}var allPrefabLst = AssetDatabase.FindAssets("t:Prefab", new []{dir});var rootNode = GetCurSceneObject("rootNode", "xxx/parent");if (!rootNode){Debug.LogError("当前场景没有找到挂载节点: " + "rootNode/xxx/parent");return;}var rootTransform = rootNode.transform;var findLst = new List<GameObject>();foreach (var guid in allPrefabLst){var path = AssetDatabase.GUIDToAssetPath(guid);var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);var find = prefab.GetComponentInChildren<RectMask2D>(true);if (!find) continue;Debug.Log("find =>: " + path);var go = PrefabUtility.InstantiatePrefab(prefab) as GameObject;if (!go) continue;findLst.Add(go);go.transform.SetParent(rootTransform, false);ReplaceRectMask2D(go);}Debug.LogError("一共找到预制: " + findLst.Count);
}

好了, 以上就是今天的内容, 希望对大家有所帮助.

Unity中使用代码将预制加载到场景相关推荐

  1. Unity中的三种资源加载和卸载

    前言 内容转载自: https://www.cnblogs.com/zhoujiangyue/articles/7066070.html. Unity中三种资源加载方式: 1.静态引用.具体操作:创建 ...

  2. java中静态变量,静态代码块,静态方法,实例变量,匿名代码块的加载顺序

    1. java中静态变量,静态代码块,静态方法,实例变量,匿名代码块 在Java中,使用{}括起来的代码称为代码块,代码块可以分为以下四种: (1)普通代码块:就是类中方法的方法体 public vo ...

  3. html层叠云标签代码,可以加载个人博客中,非常炫的特效

    原文:html层叠云标签代码,可以加载个人博客中,非常炫的特效 源代码下载地址:http://www.zuidaima.com/share/1836751885634560.htm 云标签,可以加载个 ...

  4. Unity实现扇形Slider进度条加载功能

    Unity实现扇形Slider进度条加载功能 前言 在实际的开发项目中,再跳转场景的时候可以加一个进度条显示的功能,这样在跳转场景的时候就不会显得很突兀.在进度条的实现方式中,有很多的方式,例如Uni ...

  5. 在 Swift 中使用闭包实现懒加载

    本文讲的是在 Swift 中使用闭包实现懒加载, 原文地址:Swift Lazy Initialization with Closures 原文作者:Bob Lee 译文出自:掘金翻译计划 译者:ls ...

  6. 如何在React Native中创建精美的动画加载器

    by Vikrant Negi 通过Vikrant Negi 如何在React Native中创建精美的动画加载器 (How to create a beautifully animated load ...

  7. java懒加载注解_在springboot中实现个别bean懒加载的操作

    懒加载---就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中. @Lazy 在需要懒加载的bean上加上@Lazy ...

  8. Springboot Web应用中服务器配置参数ServerProperties的加载

    #概述 Springboot配置文件中以server开头的项表示服务器的配置参数,这一点从字面意义即可直观理解,这些参数,包括端口,路径设置,SSL配置参数等等.具体有哪些参数,从源代码的角度上,可以 ...

  9. unity下载模型到本地并加载

    目录 1.目的 2.参考 2.1 Unity3D 动态加载本地/网络GLB模型 2.2 unity下载模型到本地并加载 2.3 插件:TriLib2.0 3.注意 4.操作 4.1 3dmax简单的制 ...

最新文章

  1. SpringBoot (一) :入门篇 Hello World
  2. dispatch_queue_create(com.biostime.xxx, DISPATCH_QUEUE_SERIAL)的陷阱
  3. 0x11.基本数据结构 — 栈与单调栈
  4. 源码分析Handler机制
  5. java执行器是什么_java使用Executor(执行器)管理线程
  6. Laravel插件推荐
  7. 【转载】查看MSSQL数据库每个表占用的空间大小的方法
  8. php 模拟并发请求_PHP模拟并发请求
  9. 三角函数公式总结(四)
  10. 9、MySQL逻辑架构介绍
  11. 贺利坚老师汇编课程30笔记:将数据、代码、栈放入不同段
  12. SQLServer游标详解
  13. 本特利电涡流传感器 330876-02-90-01-CN
  14. 直接加QQ好友的链接或会话的方法
  15. 关于ps中钢笔工具的介绍
  16. 联想微型计算机不支持xp,联想台式机不能装xp怎么办
  17. timestamp与datetime使用
  18. JDBC基础理解与实现操作
  19. 【UE4_蓝图】map函数以及Clamped和Unclamped的区别
  20. C语言习题:猜数字游戏(C语言随机数)

热门文章

  1. golang data race 竞态条件
  2. 让作业飞吧,与屌丝兄弟们分享我的分布式作业调度平台 【拥抱开源,拥抱作业调度的神器Quartz.net】...
  3. oracle导入 不是dba,IMP-00013: 只有 DBA 才能导入由其他 DBA 导出的文件
  4. 高级 JavaScript Day04 | 正则表达式
  5. 【Codecs系列】视频会议中的AV1编解码器
  6. CAE工程服务2022年全球行业分析报告
  7. 30个顶级Python库 | 用于深度学习、自然语言处理和计算机视觉
  8. apk安装法之三--application/vnd.android.package-archive是什么?
  9. openVswitch(OVS)源代码之linux RCU锁机制分析
  10. 仙人掌问题(圆方树)