猿问

关于 Unity3D SOLID SRP 的建议

我目前正在 Unity3D 中制作游戏,并在学习过程中尝试将 SOLID 的单一职责原则应用到我的游戏中。

我想知道是否有人可以更多地解释一下 SRP 的良好实施是什么样子,因为我觉得我正在破坏它。

我将我的课程分为基础部分:

  • PlayerInput.cs - 获取输入并将其存储到变量中(水平、垂直、人民币等)

  • PlayerController.cs - 处理攻击和玩家状态(空闲、移动、攻击)ATM

  • PlayerMovement.cs - 处理移动和旋转(看看鼠标)

  • AnimationController.cs - 处理所有动画

当我开始时,我觉得我遵循的是 SRP,但现在游戏变得越来越复杂。上面列出的每个类都会引用其他类,这似乎是不必要的。我在每个类中使用了大约 5 个 GetComponents,这似乎是重复的,因为它们都在同一个对象上。换句话说,SRP 似乎需要更多工作,并且降低了效率。

例如,PlayerController 和 PlayerMovement 脚本都有对 AnimationController 的引用,其中 AnimationController 也有对两者的引用。所有脚本都有对 PlayerInput 的引用。(请记住,为了保持简单,我省略了其他与玩家相关的脚本,例如制作和装备,但我的 Start 和 Awake 方法充满了一堆 GetComponent 调用)

谁能向我更好地解释 SRP,并可能为我指明正确的方向,这样我就不会在同一个 GameObject 上过多地使用 GetComponent 了。


小怪兽爱吃肉
浏览 104回答 2
2回答

一只名叫tom的猫

您已经正确地识别了问题,无论理论原理如何,这显然都需要解决。但好吧,我们先讨论 SRP:SRP 引用了两个较旧的概念,即耦合和内聚。不幸的是,“SRP”这个名字令人困惑、含糊不清,并且只包含等式的一方面,即分割东西。它没有提到属于在一起的东西实际上应该在一起。因此,这一切的目的是实现可维护性,这是减少未来工作的简写。要做到这一点,相互引用的事物实际上应该在一起似乎是合理的。这意味着处理某些数据的方法应该与该数据位于同一位置(即在同一对象中)。松散相关的内容(即很少互相引用)应该分开。在实践中如何做到这一点取决于业务案例,并且并不总是显而易见的。我建议做一个练习。把这些东西放在一个类中,称之为Player例如。简化它,删除所有 setter/getter 和间接。然后尝试查看是否存在仅松散地相互引用的区域,或者仅在一个方向上引用的区域。这些将是很好的候选者。尝试分割有意义的东西而不是技术性的东西,即,,,Movement都是好的,,,都是有问题的(尽管并不总是坏的)。AttackPlayerControllerAnimation

红糖糍粑

听起来您所指的内容与 SRP 无关。从最基本的角度来说,SRP 意味着您拥有的任何类都应该只“负责”一件事。您PlayerInput负责跟踪玩家通过其接口设备提供的内容,PlayerController根据多种因素提供有关玩家的状态信息,等等。您似乎指的是与 DRY(不要重复自己)原则更相关。DRY 很棒,它为抽象和代码重用提供了强大的支柱,但这并不是福音。事实上,SOLID 原则之一——依赖倒置原则——在某种程度上积极鼓励人们以灵活性的名义重复自己。如果您认为对某个方法的调用过多,则可以考虑将对该方法的一系列调用以及任何中介逻辑包装在另一个方法中,然后调用该方法。当然,这取决于需要在多个位置调用同一组指令。现在,我要说的是,您的帖子中跳出的一部分是您的AnimationController和 、PlayerController和PlayerMovement类之间的循环引用。这实际上违反了 SRP 和其他一些良好设计的原则,因为封闭的类现在负责分配给他们的任务,并且至少跟踪 中发生的事情,并且在最开始的时候AnimationController。大多数,调用自身的方法AnimationController。您应该考虑重构更细粒度的类,以便无论发生什么情况它们都能够完成自己的工作AnimationController,反之亦然。封闭类应该处理告诉封闭类要做什么的逻辑,本质上是为封闭类做出决定。
随时随地看视频慕课网APP
我要回答