好久没有写文章,这段时间恶心与快乐并行这,总之希望大伙不要忘记我,今天得空我来更新一篇最近的心得。
Prefab in Prefab的需求太多了(据可靠消息unity2018官方会支持这个功能),以前我也写过一个解决方案,但是后来自己都不用了。今天我写的这篇是自己使用过一段时间,并且觉得还不错的方法。
先说说灵感吧,前段时间再做assetbundle的打包。特效把我头疼坏了,说到特效我不得不啰嗦两句。特效美术最终都会把特效做成prefab保存在项目里,例如放在了Resources目录。程序或运行时读取,或者直接拖入到某个Prefab中来使用。
特效分三类
1.场景特效,特点是不需要运行时加载,由地编美术把特效拖入场景中完成。这类特效是被场景引用自身的关系还在prefab上,换句话说只要特效的prefab变了场景里引用它的地方也就变了,我们只需要把prefab管理好就可以。
2.我重点要说的就是第二类特效,例如人物身上绑定的特效,或者UI上绑定的特效。 人物和UI本身就是prefab,如果把特效关联上一旦apply后,这个特效就和之前的prefab断开了。未来如果要打assetbundle就需要考虑特效的依赖关系了。
3.最后一类也很恶心, 又要放在场景上、又要运行时加载、。。。。。对这类特效我不予以评价!
这时候可能就会有同学说,不把特效直接依赖上去,而是采取运行时load的形式不就完了。确实是这样,但是这样的问题就是预览起来非常麻烦。尤其UI上的特效,只要调位置都得运行起来看,还有一些特效的出现时机是需要逻辑满足才播放,这样调起来就更麻烦了。
废话了这么多,说说今天的重点,我要让prefab嵌套prefab,并且很方便的预览,还要使用者点击apply不能破坏原有的依赖结构。
我们可以监听GameObject在Hierarchy视图中选择的事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#if UNITY_EDITOR [CustomEditor(typeof(UICacheBase))] public class UICacheBaseInspector : Editor { void OnEnable() { if (!Application.isPlaying) { if (target != null) { //1.清空节点 //2.实例化prefab,设置不可被保存 //3.即可在hierarchy中预览 } } } } #endif |
1.清空节点 保证节点下没东西
1 2 3 4 5 |
while(transform.childCount >0){ GameObject.DestroyImmediate (transform.GetChild (0).gameObject); } |
2.实例化prefab ,设置不可被保存,也就是apply后不会再被保存在prefab上。
实例化prefab,就是根据一个路径去load(序列化好),实例化到hierarchy视图中,并且设置这个gameObject的属性,不可编辑,以及不可能被保存.
1 2 3 4 5 6 7 |
#if UNITY_EDITOR foreach (Transform t in go.GetComponentsInChildren<Transform>()) { t.gameObject.hideFlags = HideFlags.NotEditable | HideFlags.DontSave; } #endif |
3.此时在Scene视图中就可以预览效果了。
这里我举个例子,如下图所示,我有一个父Prefab需要嵌套一个子Prefab(特效),我把子Prefab(特效)拖入右侧resPrview处。即可直接在Hierarchy视图中预览,resPreview这个脚本只需要序列化保存了特效的路径. 无论你怎么Apply父Prefab也不会把子Prefab(特效)包含在父Prefab中了。
文章中的例子可能比较简单,因为实际游戏中嵌套的Prefab可能还需要一些自身的逻辑,不仅仅是隐藏/显示/加载 这么简单的操作。
下一篇我会讲一讲我用这个思路做的UI缓存策略,很有意思!可以让你的UI打开速度更快。
- 本文固定链接: https://www.xuanyusong.com/archives/4422
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
重新描述下,这个HideFlags.DotSava在2018.4已经不会被保存进预制体里面了,就算我们Apply,标记为DoneSave不会保存进去
我这边有个意见就是把每个ui单独做成一个场景来管理 然后 其他特效的prefab直接拖入保存引用关系。可以直接预览。然后 通过prefabUtility 导出一个prefab。这样特效修改的时候 只要场景自动导出一下新的prefab就好了。也可以结合你的自动加载特效代码来用。
momo,你好。这里主要解决的需求类似,ui界面挂特效,而且特效可能会频繁修改。导致如果将特效挂在ui中,且apply ui后,导致特效在hierarchy中与prefab断开连接,最终加长工期,浪费时间。然后这里有几个问题,
1.UICacheBase这个到底是挂在当前编辑的预制上吗?为啥要清空节点下的对象?
2.resPreview和UICacheBase啥关系
3.这里特效调整位置,也没有任何地方记录啊。或者有啥解决方案吗?
看完一头雾水啊…
ps:这里不能注册了么
可否公开res preview的代码?
友情提醒下,DotSave的意思是不被场景管理,而不是不保存。它最后还是会被保存在预制里的,你觉得它没存有可能是因为Enabled的时候自己清掉了。
现在并没有创建在预制子级并且不会被Apply操作影响的办法。
一定要做恐怕只能在prefabInstanceUpdated中处理。
notsave目前我只用来预览,其实我到导出UI界面的时候,还会强制清空一下这种节点下的东西。 所以它不会被留在prefab里。
试验了下,这个DotSava在2018.4已经够不会被保存进去了预制体里面了