unity3d 收费模式

抽象 (Abstract)

Game development as a discipline is challenging on its own compared to traditional software development. The ability to solve performance-related, architectural and other challenges is often the key to success in the field. Because of these and many other factors, it is often a good practice to follow certain software principles and common practices to enforce the maintainability and extensibility of a product. Software design patterns come in handy in such scenarios. They can make the code base more maintainable, extensible, and contribute significantly to the overall lifetime of a product. One of the use cases to be examined is the application of the visitor pattern (Gamma, et al. 1995) in the context of game development. Possible challenges and benefits of the pattern implementation are outlined respectively in this writing.

与传统软件开发相比,将游戏开发作为一门学科本身具有挑战性。 解决与性能相关,体系结构和其他挑战的能力通常是该领域成功的关键。 由于这些因素和许多其他因素,遵循某些软件原理和通用惯例来强制执行产品的可维护性和可扩展性通常是一个好习惯。 在这种情况下,软件设计模式会派上用场。 它们可以使代码库更具可维护性,可扩展性,并为产品的整个生命周期做出重大贡献。 要研究的用例之一是访客模式在游戏开发中的应用(Gamma等,1995)。 本文分别概述了模式实现的可能挑战和好处。

前言 (Preface)

The scenario used is completely fictional and resembles an isolated use case. The degree of design completeness in the classes is not meant to be a subject for evaluation of any kind and is simplified to emphasize the point of the paper and not to clutter the code with proper, secure programming construction. Edge case checks are omitted along with many other optimization-related techniques to illustrate the point of the topic.

使用的场景完全是虚构的,类似于孤立的用例。 这些类中的设计完整性程度并不意味着要进行任何形式的评估,而应简化以强调本文的要点,并且不要以正确,安全的编程结构使代码混乱。 省略了边缘案例检查以及许多其他与优化相关的技术,以说明该主题的重点。

This writing is a purely personal interpretation and vision of the matter based on the challenges I have encountered while coding and trying to accept Unity3d component-based architecture.

基于我在编码和尝试接受基于Unity3d组件的体系结构时遇到的挑战,本文只是对此问题的纯个人解释和构想。

Full source code can be found in my GitHub repo: https://github.com/george-vasilchenko/unity-visitor

完整的源代码可以在我的GitHub存储库中找到: https : //github.com/george-vasilchenko/unity-visitor

问题 (The Problem)

To examine the usefulness and applicability of the visitor pattern within game logic, we sketch the following scenario. Consider the following diagram, to begin with:

为了检查游戏逻辑中访客模式的有用性和适用性,我们绘制了以下场景。 首先考虑下图:

The setup is quite straightforward. We have an abstract base class with a few common members for a character. See the code for the CharacterBase class:

设置非常简单。 我们有一个抽象基类,该基类有几个常见的角色成员。 请参见CharacterBase类的代码:

Each of the child classes implements the required members accordingly. The characters have a default set of stats assigned during the initialization. The starting level for each character is 1. To perform an attack, according to my fictional scenario, it is important to calculate damage for the attack. There are hundreds of ways this can be implemented of course but, in my case, it will be a calculation based on the weighted distribution of the stats of a particular character. Here is the implementation of the Attack and CalculateDamage methods from the Archer class:

每个子类都相应地实现所需的成员。 这些字符在初始化期间分配了一组默认的统计信息。 每个角色的起始级别为1。根据我的虚拟场景,要进行攻击,计算攻击的伤害很重要。 当然,有数百种方法可以实现,但就我而言,这将基于特定角色的统计信息的加权分布进行计算。 这是Archer类中AttackCalculateDamage方法的实现:

The idea is that each character, based on its type (Archer, Paladin, etc) has its leading trait. Archer, for instance, has agility as his main trait. In contrast, a magician uses intelligence as the main characteristics. This trend is implemented in the CalculateDamage methods for each of the characters.

这个想法是,每个角色根据其类型(Archer,Paladin等)都有其主导特征。 例如,弓箭手以敏捷为主要特征。 相反,魔术师则以智力为主要特征。 此趋势在CalculateDamage方法中为每个字符实现。

The problem here, however, is that we keep this distribution information in each character class. At the first sight, this seems reasonable, but if we will implement a more advanced way of resolving these numbers, we will need to introduce dependencies in each character class and the code will become less flexible.

但是,这里的问题是,我们在每个字符类中保留了此分发信息。 乍一看,这似乎是合理的,但是如果我们将采用更高级的方式来解析这些数字,则需要在每个字符类中引入依赖关系,并且代码的灵活性将降低。

Let’s consider another scenario for the characters. The ability to level-up in the game can be a desired feature. Usually, this kind of functionality is essential. The ability to increase the level, in my scenario, impacts the damage amount that a character can produce. With each level, normally, a character would deal more and more damage, this is also the case in my fictional scenario. Consider the following implementation of the IncreaseLevel method:

让我们考虑字符的另一种情况。 在游戏中升级的能力可能是理想的功能。 通常,这种功能是必不可少的。 在我的情况下,提高等级的能力会影响角色可能产生的伤害量。 通常,在每个级别上,角色都会造成越来越多的伤害,在我的虚拟场景中也是如此。 考虑下面的GrowthLevel方法的实现:

We increment the level member variable each time the method is called. For us to come up with a proper stat increase for a given level, we should increment each stats property each time the level is increased. Using the CreateFromOtherWithDeltas method of structure CharacterStats, gives us the updated stats instance that is built on top of the existing one and with the delta for each property. The implementation of the CharacterStats structure:

每次调用该方法时,我们都会增加级别成员变量。 为了让我们针对给定的级别提出适当的统计信息增加,每次级别增加时,我们都应该增加每个统计信息属性。 使用CharacterStats结构的CreateFromOtherWithDeltas方法,可以为我们提供更新的stats实例,该实例建立在现有实例的基础上,并具有每个属性的增量。 CharacterStats结构的实现:

To sum it up, we calculate stats deltas based on the level of the character and we update the stats reference with a new object. This, in turn, will be used in the CalculateDamage method to come up with the final damage amount.

综上所述,我们根据字符的级别计算统计数据增量,并使用新对象更新统计数据引用。 反过来,它将在CalculateDamage方法中使用,以得出最终的损坏量。

The direction where this implementation is heading is obvious. We keep extending the class with the implementation of every new level, besides, in a more advanced scenario, the resolution of the stats values would be delegated to an external class which in turn would become a dependency for the character class. And this repeats for each new character we desire to add in the game. This will bring maintenance problems, high complexity of the character classes, and tight coupling between possible external modules that provide numeric data for this logic.

该实现的方向很明显。 我们将通过每个新级别的实现来扩展类,此外,在更高级的情况下,统计值的解析将委派给外部类,而外部类又将成为字符类的依赖项。 对于我们希望添加到游戏中的每个新角色,此操作都会重复。 这将带来维护问题,字符类的高度复杂性以及可能为此逻辑提供数字数据的外部模块之间的紧密耦合。

有希望的解决方案 (The Promising Solution)

The Visitor pattern, according to Gamma, et al. (1995), is intended to

访客模式,根据Gamma等人的说法。 (1995),旨在

“represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.”

“表示要在对象结构的元素上执行的操作。 访问者可让您定义新操作,而无需更改其所操作元素的类。”

This definition strikes as a possible solution to achieve the needed maintainability in the classes from the fictional scenario. Let’s try to implement such a pattern and analyze whether it will enhance the quality and design of the program.

该定义是从虚拟场景中实现类中所需的可维护性的可能解决方案。 让我们尝试实现这种模式,并分析它是否会提高程序的质量和设计。

I have gone ahead and refactored the code to fit the pattern. A few more classes have emerged. Consider the new diagram:

我已经继续并重构了代码以适应模式。 出现了更多的类。 考虑新图:

Types like IDamageable and Enemy are just supplementary components to make the scenario more or less complete, they are used in the Attack method of each character. I have introduced a few more types, specifically ICharacterVisitor<T> and two implementations of this interface: StatsDistributionVisitor and StatsIncreasePerLevelVisitor. The first one was designed to take responsibility for the distribution logic that is used by each character in a specific way, and the latter is meant to tackle the level-based stats problem. I moved all related code from the character classes into the visitor classes respectively. StatsDistribution structure was introduced to encapsulate the concept of stats deltas. The code for the distribution visitor:

诸如IDamageableEnemy之类的类型只是使场景或多或少完整的补充组件,它们在每个角色的Attack方法中使用。 我介绍了更多类型,特别是ICharacterVisitor <T>和此接口的两个实现: StatsDistributionVisitorStatsIncreasePerLevelVisitor 。 第一个设计用于负责每个角色以特定方式使用的分配逻辑,而后者则旨在解决基于级别的统计问题。 我将所有相关代码分别从字符类移到了访客类。 引入了StatsDistribution结构来封装stats deltas概念。 分发访问者的代码:

Here we can see that values that were provided in the CalculateDamage method are moved into this class and it is way easier to maintain this structure. The stats distribution logic is now in one place and can be easily extended by any external source. For instance, we can use a ScriptableObject (Unity, 2018) instance to manipulate these values from the Editor, which would be a good solution for level designers and testers.

在这里,我们可以看到CalculateDamage方法中提供的值已移入此类,并且可以更轻松地维护此结构。 统计信息分配逻辑现在处于一个位置,可以通过任何外部源轻松扩展。 例如,我们可以使用ScriptableObject (Unity,2018)实例从编辑器中操纵这些值,这对于关卡设计人员和测试人员而言将是一个很好的解决方案。

The second visitor class is responsible for determining a boost for the stats for each character based on the level. Here is the implementation in code:

第二个访问者类负责根据级别确定每个角色的属性提升。 这是代码中的实现:

The level stats logic was moved from the character classes into the visitor class. Similarly, this class can also take advantage of additional dependencies. This approach takes the burden concerning level-based upgrades away from the character classes.

级别统计逻辑已从角色类移至访客类。 同样,此类也可以利用其他依赖项。 这种方法减轻了基于角色升级的负担。

Let’s take a look at the actual use of the visitor classes by, say, the Mage class:

让我们看一下Mage类对访客类的实际使用:

The size of the class is reduced. The amount of level related logic will no longer affect this class because the logic is placed in the visitor class. The distribution logic is also substituted with the call to the Visit method of the distribution visitor.

班级人数减少。 与级别相关的逻辑的数量将不再影响此类,因为该逻辑已放置在visiter类中。 分发逻辑也用对分发访问者的Visit方法的调用代替。

测试中 (Testing)

To try out both implementations, I have set up a few simple editor-based unit tests. The tests take care of creating instances of the characters. Each character gets its enemy to attack. To not overengineer the scenario and to not sway from the topic, the assessment logic simply examines the change in the health of each enemy. Additionally, the information is logged into the console to illustrate the difference. The tests are identical concerning the implementation before the visitor pattern and after, the only difference is the character class implementations. Here is the sample code for one of the tests:

为了尝试这两种实现,我建立了一些简单的基于编辑器的单元测试。 测试负责创建字符实例。 每个角色都会受到敌人的攻击。 为了不对场景进行过度设计并且不偏离主题,评估逻辑仅检查每个敌人的健康状况变化。 此外,该信息将记录到控制台中以说明差异。 关于访问者模式之前和之后的实现,测试是相同的,唯一的区别是字符类实现。 以下是其中一项测试的示例代码:

The results of the tests are identical. Here is the result for the implementation without the visitor pattern:

测试结果是相同的。 这是没有访问者模式的实现结果:

Here is the result after the visitor pattern was implemented:

这是实现访客模式后的结果:

思想 (Thoughts)

Considering the amount of effort it takes to implement game logic in game development, it is essential to find an efficient way to do that. Using software design patterns is considered good practice but the patterns have to be applied with a reason and caution. It is often tempting to over-complicate design and implementation, which, in result, puts the success of a product at risk. Unity3d coding approach follows a component-based design (Component-based software engineering, 2020). It is quite challenging to follow object-oriented principles in such an environment when architecture works against you. However, in certain isolated components, it is possible to tackle problems by following common best practices. The visitor pattern appears to be useful in scenarios when we have to deal with multiple objects of the same structure that have to implement certain operations. Visitor lets us keep related operations together by defining them in one class (Gamma, et al. 1995). This opens additional opportunities to make use of the reach feature set of the engine when we want to influence the data of the visitor classes.

考虑到在游戏开发中实现游戏逻辑所需的工作量,找到一种有效的方法至关重要。 使用软件设计模式被认为是一种很好的做法,但是必须谨慎使用这些模式。 通常,设计和实现过于复杂是很诱人的,这最终使产品的成功受到威胁。 Unity3d编码方法遵循基于组件的设计(基于组件的软件工程,2020)。 当架构不利于您时,在这样的环境中遵循面向对象的原则是非常具有挑战性的。 但是,在某些隔离的组件中,可以通过遵循常见的最佳实践来解决问题。 当我们必须处理必须执行某些操作的具有相同结构的多个对象时,访问者模式在场景中很有用。 访客可以通过将它们定义在一类中来使相关操作保持在一起(Gamma等,1995)。 当我们想影响访问者类的数据时,这为利用引擎的覆盖范围功能集提供了更多机会。

后记 (Afterword)

The implementation of the visitor pattern lacks the so-called common Apply method. This is done intentionally and considered unnecessary by me because the way the instances of the visitor classes are resolved satisfies the overall idea of the pattern. Of course, it is possible to add another level of abstraction in the character classes such as ArcherDamageSystem, ArcherStatsSystem that would in turn use the visitor classes and expose the Apply method, but I believe this is not the point here and ignoring Apply method is acceptable due to the circumstances.

访问者模式的实现缺少所谓的通用Apply方法。 这是有意完成的,我认为这是不必要的,因为解析访问者类的实例的方式满足了该模式的整体思想。 当然,也可以添加在字符类如ArcherDamageSystem,ArcherStatsSystem这反过来将使用访问者类和揭露应用方法另一层抽象的意义,但我相信在这里这并不是问题的关键,而忽略应用方法是可以接受的视情况而定。

翻译自: https://medium.com/the-innovation/visitor-pattern-in-unity3d-6f70f60db75d

unity3d 收费模式


http://www.taodudu.cc/news/show-5677342.html

相关文章:

  • java 访客模式,设计模式 - 访客模式( Visitor Pattern)
  • 访客模式 无痕模式 区别_行为设计模式:访客
  • android访客模式,访客模式:我的隐私我做主_小米 红米Note(增强版/移动3G/2GB RAM)_手机Android频道-中关村在线...
  • 模式:访客模式
  • 访客模式 无痕模式 区别_访客设计模式
  • java 访客模式_java – 访客模式是否包含某些状态?
  • Chrome的隐身模式与访客模式的差异
  • ffbe攻略站_【FFBE幻影战争攻略】狮国都有哪些角色(详细教程)
  • 到底该如何爱上编程?
  • 一个人的武林
  • 五轮书
  • PHP 毕生功力 图片,凝聚毕生功力
  • 文件的上传与下载及解决文件重名问题
  • 84---Python 雨滴模拟
  • 洛谷p2698
  • js模拟动态图的雨滴掉落
  • c语言变大变小的图片,51单片机模拟水滴由小变大然后滴落现象(附带C语言源码)...
  • joint绘制流程图
  • 在RIVZ下,利用程序让自己的joint动起来
  • Unity中HingeJoint控制开门
  • Unity-Spring Joint 2D组件
  • 解析HTML流程图,JointJS JavaScript流程图绘制框架解析
  • 怎么使用jointpoint软件
  • VREP joint关节
  • jointjs -- link
  • Joint Face Image Restoration and Frontalization for Recognition 论文笔记
  • 6.3.3 URDF语法详解03_joint
  • Simscape multibody(原simmechanics)中关于joint的解释
  • 拷屏截屏快捷键
  • webstrom 快捷键

unity3d 收费模式_unity3d中的访客模式相关推荐

  1. Go设计模式--访客模式

    大家好,这里是每周都在陪你一起进步的网管-!今天继续学习设计模式-访客模式 访客模式也叫访问者模式(Visitor Pattern)是一种将数据结构对象与数据操作分离的设计模式,可以在不改变数据结构对 ...

  2. android访客模式,访客模式:我的隐私我做主_小米 红米Note(增强版/移动3G/2GB RAM)_手机Android频道-中关村在线...

    访客模式 相信每个人的手机中总有一些比较私密的短信.照片.程序等,当然对于这些东西我们并不想被别人知道和看见.而在日常生活中,总避免不了别人偶尔使用或者查看自己的手机,那么这些私密的东西就会让我们变得 ...

  3. 如何以访客模式访问_重新访问了访客模式

    如何以访客模式访问 访客模式是面向对象设计中最被高估但又被低估的模式之一. 高估了它,因为它通常选择得太快了( 可能是由建筑宇航员选择的 ),然后以错误的方式添加后,使原本非常简单的设计肿了. 如果您 ...

  4. instanceof运算符_Java 8中的instanceof运算符和访客模式替换

    instanceof运算符 我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长. 所以我想出了以下DSL语法: Object msg = //...whenTy ...

  5. Java 8中的instanceof运算符和访客模式替换

    我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长. 所以我想出了以下DSL语法: Object msg = //...whenTypeOf(msg).is(D ...

  6. oracle无效的关系运算符_每日一课 | Java 8中的instanceof运算符和访客模式替换

    我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长.所以我想出了以下DSL语法: Object msg = //... whenTypeOf(msg).     ...

  7. java 访客模式,每日一课 | Java 8中的instanceof运算符和访客模式替换

    每日一课 | Java 8中的instanceof运算符和访客模式替换 每日一课 | Java 8中的instanceof运算符和访客模式替换 我有一个梦想,不再需要操作员和垂头丧气的instance ...

  8. java网页统计访客量_Java中的访客设计模式

    java网页统计访客量 Visitor Design Pattern is one of the behavioral design pattern. 访客设计模式是行为设计​​模式之一. 访客设计模 ...

  9. 访客模式 无痕模式 区别_模式:访客模式

    访客模式 无痕模式 区别 问候, 这周我们放开所有代数的内容,然后集中精力 面向对象编程的全部内容. Java声称支持OO,因此 为什么不使用它? 在本周的文章中,我们将讨论一下何时 以及为什么要应用 ...

最新文章

  1. 在Visual C++下搭建OpenGL的开发环境
  2. mysql报196271错误_超过mysql最大连接的异常
  3. 智能摄像头——小觅智能摄像头
  4. Index of XML
  5. 自定义taglib引入失败_小程序拼团总失败?看看微信官方和开发者们怎么说
  6. 【Python】Python随机数random模块的应用
  7. 5件最灵异的事~~~~~~~~~~~~~~~~~~转
  8. 泰森中国宣布与阿里云达成战略合作
  9. 实验1 数字图像处理的MATLAB基础,《数字图像处理(实验部分)》实验1_数字图像处理中MATLAB使用基础...
  10. Kerberos工作流:一个简单示例
  11. S7503E V7 snmpv3典型组网配置案例(与IMC联动)
  12. 【React 】基于Antd Design的CheckBox多选框组件封装
  13. 蓝牙网关走进智慧校园
  14. 约束的操作 - 增加 删除 禁止 启用
  15. python爬虫微博图片_python爬取微博图片及内容
  16. ctP2ISP:使用卷积和数据增强的转换器预测蛋白质-蛋白质相互作用位点
  17. 高品质蓝牙耳机排行榜,优质蓝牙耳机推荐
  18. 微信小程序如何引用iconfont图标
  19. Python识别条码内容
  20. MySQL-8.0.26-winx64安装时出现服务正在启动,服务无法启动解决方法

热门文章

  1. python无限循环语句纵向输出字符串,python-urwid-无限循环的输出屏幕
  2. AutoCAD 2009中文版基础入门教程下载
  3. FarPoint.Web.Spread 那些事
  4. ABAP 固定资产报废的BAPI
  5. my traceroute
  6. 版本更新android联想,终于升级到Android10,联想ZUI11.5 内测版上线
  7. Linux主机文件777,755,644权限详解
  8. java暑假_Java暑假作业
  9. java要早九晚九吗_纠结吗?朝九晚九每周七天997的工作offer年薪50万接不接
  10. 【元宇宙欧米说】NFT藏品的前景与未来应用