2

我正在使用 Unity3D 编码 C# 开发游戏。

由于我是从纯 OOP 环境来到 Unity,因此基于组件的方法对我来说毫无意义。因此,对于我们的武器系统,我使用继承树和对象层次结构的方法纯粹采用 OOP。我花在代码上添加新功能和东西的时间越多,我发现这种设计就越不灵活。所以现在我倾向于基于组件的设计。

我在这里发布了我的问题,询问如果我使用组合优于继承的方法是否足够好,正如Jamora 先生在这里所建议的那样。

他的解决方案听起来非常好。但是如果我有不止一种武器,那么就不足为奇了,实现相同的逻辑让我们说ReloadIReloadable

public interface IReloadable
{
   void Reload();
}

public interface IUpgradable
{
   void Upgrade();
}

public interface IShooter
{
   void Shoot();
}

public SMG : IShooter, IReloadable
{
   void Shoot()
   {
       // shooting logic 1
   }
   void Reload()
   {
       // reloading logic 1
   }
}

public AssaultRifle : IShooter, IReloadable, IUpgradable
{
   void Shoot()
   {
       // shooting logic 2
   }
   void Upgrade()
   {
       // upgrade logic 1
   }
   void Reload()
   {
       // reloading logic 1 -- SAME LOGIC
   }
}

如您所见,存在代码重复,我不喜欢这样。这可以避免吗?(以干净、灵活的方式)

总的来说,这(组合优于继承)是在 Unity 中制作武器系统的好方法吗?- 或者最好使用 Unity 的基于组件的方法,并制作一个ShooterReloadable组件(脚本)并将它们附加到我的武器游戏对象?

在此先感谢您的帮助。

4

3 回答 3

1

感谢任何试图提供帮助的人。实际上,我从 Jamora 那里得到了一个很好的解释,在我上面发布的同一个链接[link]上。但我再也没有时间分享它了。

然而,我发现你不能把所有东西都做成一个组件,例如,一个Reloadable或一个Shooter组件。除非你所有的武器都以相同的方式重新加载/射击,否则你不能创建这样的组件并将其附加到它们上,因为如果武器重新加载/射击不同,这意味着该信息应该在武器本身中(即抽象Weapon可能带有抽象ReloadShoot方法),因此组件不知道该信息。

另一个示例,制作Usable脚本组件以附加到您的项目。你不能这样做,那没有意义。使用保健品,不同于使用钥匙开门。使用信息存储在项目本身中。附加Usable到一个项目,意味着所有项目都以相同的方式使用。

我还发现,继承是必须的,即使在 Unity 中也是如此。但坏事是所有设计都依赖于纯对象层次结构树。相反,创建小树的混合,为不同的行为实现接口,并尽可能创建脚本组件。

于 2013-10-22T07:52:11.697 回答
0

如果您遵循 Unity3D 约定,特别是如果您使用 javascript,则首选(强制)使用 Composition。

但是,看起来您使用的是 C#,在这种情况下您可以选择。

只要你不违反 DRY,那么这真的取决于你的喜好。但是已经建立了统一来处理组合。(另一方面,我更喜欢继承)

于 2013-10-21T19:16:52.727 回答
0

是的,组合是可重用代码的最佳选择,可防止重复和复制粘贴代码。你没有使用组合,你只使用了继承和接口。最好的过程是实现 IReloadable Ishootable ,... 接口和 Reloadable1,shootable1,Reloadable2,shootable2,... 继承 IReloadable,Ishootable 的类。然后您可以使用 Reloadable1,shootable1,Reloadable2,shootable2,.. 武器组件。所以如果你想改变任何东西,你只需要改变一个组件(例如Reloadable2)

于 2016-08-01T10:08:25.400 回答