我在几个地方问了这个问题,但还没有完全弄清楚,所以也许一些聪明的人会想到如何解决这个问题。
在项目中维护预制件的深层嵌套层次的最佳方法是什么?假设我们有几个由较小的通用组件组成的GUI屏幕。为了简单起见,我们将前者称为“视图”,将后者称为“组件”。视图处理语义(例如库存视图,商店视图);组件是可配置的,但没有任何附加的业务逻辑(例如,按钮仅关心其OnTap回调/事件处理程序)。
视图和组件都可以嵌套。
GUI视图需要在多个场景之间重用。
Unity中这种方法的主要问题是,任何嵌套的层次结构一旦变成预制件,便会失去对其子预制件的引用,例如以下示例(完全组成,但仍然有效):- storeView - UIViewHeader - UIHeaderLabel<Text> - UIList - UIListItem - UIThumbnail - UITitleLabel<Text> - UISubTitleLabel<Text> - UIPrimaryButton<Button> - ...
我想将所有这些较小的UI *组件保留在单独的预制件中,但还要保留storeView预制件,以便可以轻松地将其添加到不同的场景中。不幸的是,当我们创建storeView预制件时,所有UI *预制件引用都将丢失。
鉴于此,我们可以尝试一种不同的方法,在该方法中,不使用带有内容的storeView预制件,而是将其保留为空,然后选择以下几个选项之一:
在运行时将行为附加到storeView并加载子预制件
缺点:使设计人员的工作流程更加复杂,将复杂性置于脚本中,从开发人员的角度来看,也可能更容易出错
优点:可以更轻松地在场景之间重用storeView,可以对组件预制件进行样式设置,全局修改
将storeView保留为空的预制件,并在需要它的每个场景中重新组装它
缺点:组件需要手动连接,仍然很容易意外地保存整个storeView并丢失预制参考
优点:保证维护组件预制引用,允许视图之间的细微差别(实际上是个问题,因为这些应该属于配置层)
将整个storeView保存为预制件
缺点:扩展性极强,使得迭代新功能或小的UX更改更加耗时(其他质量检查,验收测试等)。
优点:这是一个快速且肮脏的解决方案,适用于小型项目
使用Prefab Evolution或类似产品
缺点:我认为该包装将被Nested Prefabs淘汰,这在路线图上是什么?要求取决于第三方代码,可能不够灵活(这里有什么意见吗?
优点:从我所看到的许多(混合)评论中,有些评论是非常正面的。但是,项目越复杂,这些评论就越不积极。
编写一堆自定义编辑器脚本:
缺点:也很耗时-似乎应该由平台提供,即使它主要处理游戏
优点:可以完全控制行为,开发人员可以在设计人员的反馈下加以改进。有人可能会争辩说,由于功能需求而受到约束,必须具有实施,测试和对设计人员友好的工具,这听起来像是一种好的设计实践(导致更少的技术负担,更易于维护)
这是我针对此的个人的,理想的,不切实际的解决方案*:
使用组件化的体系结构,默认情况下,子预制组件引用存储在复杂的预制组件中。在内部将它们视为UIView和移动(Cocoa)上的子视图,或者是React或更好的功能组件中的组件类-React / Cycle / Elm /与FRP相配的任何东西(是的,我知道这些方法在很多方面都存在差异,但关键是可组合性,可以通过功能组合物,装饰物等实现)。
缺点:我认为我的困难来自我对Unity的缺乏经验,并且有一个更明显的,也许是惯用的解决方案(我很乐意要求:))
优点:使新功能的测试和迭代更容易,使预制件更强大,同时又不损失其任何优势(如果我错了,请纠正我,我仍然熟悉Unity)
请不要以为我期望Unity提供所有这些功能,但这是可能的方向之一,即使其中1%是正确的。
明确地说,对于Unity来说并不是什么麻烦,作为一个以前使用移动(本机)和Web的开发人员,我发现它给我留下了深刻的印象,它解决了我的许多问题,以及其中一些解决方案多么简单的荒谬。
最佳答案
我可能会在单独的场景中维护合成视图。只需考虑这些场景,因为它们是预制的,只包含给定类的单个原型对象。
将SceneManager.LoadScene
与LoadSceneMode.Additive
一起使用,您甚至可以创建一些静态工厂方法,例如:
public class UIStoreView
{
public static UIStoreView Instance()
{
SceneManager.LoadScene("UIStoreView", LoadSceneMode.Additive);
return GameObject.Find("UIStoreView");
}
}
通过一些命名对流,您可以实现与
storeView = UIStoreView.Instance();
一样简单的功能。这不是通用的/可扩展的东西,但是至少您要轻巧/可维护,直到它们推出嵌套的预制件(如他们所说的timeline uncertain)。