mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 10:46:17 +00:00
提交
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# EX-GAS Wiki -- Ability
|
||||
> Ability是EX-GAS的核心类之一,它是游戏中的所有能力基础。
|
||||
>
|
||||
> 同时Ability也是程序开发人员最常接触的类,Ability的完整逻辑都是由程序开发人员实现的。
|
||||
>
|
||||
> 【EX-GAS目前没有能力的可视化编辑器,后续计划会制作Ability的编辑器,尝试实现自动化生成Ability脚本】
|
||||
>
|
||||
## 前言
|
||||
在EX-GAS内,Ability是游戏中可以触发的一切行为和技能。多个Ability可以在同一时刻激活, 例如移动和持盾防御。
|
||||
Ability作为EX-GAS的核心类之一,他起到了Do(做)的功能。
|
||||
|
||||
Ability的业务逻辑取决于游戏类型和玩法。所以不存在一个通用的Ability模板,当然可以针对游戏类型制作一些通用的ability。
|
||||
Ability的逻辑并非自由,如果胡乱的实现Ability逻辑,可能会导致游戏逻辑混乱,所以需要遵循一些规则。
|
||||
---
|
||||
Ability的具体实现需要策划和程序配合。
|
||||
这并不是废话,而是在EX-GAS的Ability制作流程中,确确实实的把策划和程序的工作分开了:
|
||||
- 程序的工作:编写Ability(Ability,AbilitySpec)类
|
||||
- 策划的工作:配置AbilityAsset
|
||||
---
|
||||
为了更好的理解,首先我来介绍Ability的Runtime运行逻辑。
|
||||
## Ability运行逻辑
|
||||
|
||||
## Ability子类的编写流程
|
||||
这一部分是针对程序开发人员的,策划人员可以粗略一览这一部分。
|
||||
|
||||
## AbilityAsset的配置流程
|
||||
这一部分是针对策划人员的,程序开发人员可以粗略一览这一部分。
|
||||
|
||||
## Ability的设计原则和一些建议
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfcc47cc435a1514c9cf242b88b4c813
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
47
JNFrame2/Assets/HotScripts/JNGame/Runtime/GAS/Wiki/EX-GAS.md
Normal file
47
JNFrame2/Assets/HotScripts/JNGame/Runtime/GAS/Wiki/EX-GAS.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# EX-GAS Wiki
|
||||
> 本页为菜单引导页,另外还会总体的概括EX-GAS的设计实现思路。
|
||||
>
|
||||
## 简介
|
||||
>EX-GAS是对UnrealEngine的GAS(Gameplay Ability System)的模仿和实现。
|
||||
|
||||
GAS 是 "Gameplay Ability System" 的缩写,是一套游戏能力系统。
|
||||
这个系统的目的是为开发者提供一种灵活而强大的框架,用于实现和管理游戏中的各种角色能力、技能和效果。
|
||||
|
||||
如果把EX-GAS高度概括为一句话,那就是:**WHO DO WHAT**。
|
||||
- Who:AbilitySystemComponent(ASC),EX-GAS的实例对象,是体系运转的基础单位
|
||||
- Do:Ability,是游戏中可以触发的一切行为和技能
|
||||
- What:GameplayEffect(GE),掌握了游戏内元素的属性实际控制权,GameplayEffect本身应该理解为结果
|
||||
|
||||
GAS本质是一套属性数值的管理系统,GameplayCue我个人理解为是附加价值(虽然这个附加价值很有分量)。
|
||||
纵使GAS的Tag体系解决复杂的GameplayEffect和Ability的逻辑,但最终的结果目的也只是掌握属性数值变化。
|
||||
而属性的最底层修改权力交由了GameplayEffect。所以我把GE理解为结果。
|
||||
|
||||
UE的GAS的使用门槛很高,这一点在我构筑完EX-GAS雏形后更是深有体会。
|
||||
所以在EX-GAS的设计上,我尽可能的做简化,优化,来降低了使用门槛。
|
||||
我制作了几个关键的编辑器,来帮助开发者快速的使用EX-GAS。
|
||||
但即便如此,GAS本身的繁多参数依然让编辑器的界面看上去十分臃肿,这很难简化,没有哪个参数是可以被删除的。
|
||||
甚至,雏形阶段的EX-GAS还有很多功能还未实现,也就是说还有更多的参数是没有被编辑器暴露出来的。
|
||||
|
||||
_**GAS的使用者必须至少有一名程序开发人员,因为GAS的使用需要编写大量自定义业务逻辑。
|
||||
Ability,Cue,MMC等都是必须根据游戏类型和内容玩法而定的。
|
||||
非程序开发人员则需要完全理解EX-GAS的运作逻辑,才能更好的快速配置出各种各样的技能和玩法表现。**_
|
||||
|
||||
## Wiki:EX-GAS的核心组成
|
||||
- [GameplayTag](#GameplayTag)
|
||||
- [Attribute](#Attribute)
|
||||
- [AttributeSet](#AttributeSet)
|
||||
- [ModifierMagnitudeCalculation](#ModifierMagnitudeCalculation)
|
||||
- [GameplayEffect](#GameplayEffect)
|
||||
- [GameplayCue](#GameplayCue)
|
||||
- [Ability](#Ability)
|
||||
- [AbilitySystemComponent](#AbilitySystemComponent)
|
||||
|
||||
## Wiki:EX-GAS辅助编辑器的使用
|
||||
- [Setting Aggregator](#SettingAggregator)
|
||||
- [Gameplay Tag Manager](#AttributeSetEditor)
|
||||
- [Attribute Manager](#AttributeSetEditor)
|
||||
- [AttributeSet Manager](#AttributeSetEditor)
|
||||
- [GAS Asset Aggregator]()
|
||||
- [Gameplay Effect](#GameplayEffectManager)
|
||||
- [Ability](#AbilityAssetManager)
|
||||
- [AbilitySystemComponent](#GameplayCueManager)
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 557be2d0ed7ffbf469523d1a6bfcc515
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,67 @@
|
||||
# EX-GAS Wiki -- GameplayCue
|
||||
>目前EX-GAS的GameplayCue功能还未完善。功能相对简陋。
|
||||
## GameplayCue的作用
|
||||
GameplayCue是一个用于播放游戏提示的类,它的作用是在游戏运行时播放游戏效果,比如播放一个特效、播放一个音效等。
|
||||
|
||||
## GameplayCue的原则
|
||||
Cue是游戏提示,他必须遵守以下原则:
|
||||
- _**Cue不应该对游戏的数值体系产生影响,比如不应该对游戏的属性进行修改,不应该对游戏的Buff进行修改等。**_
|
||||
- _**Cue不应该对游戏玩法产生实际影响,比如即时战斗类的游戏,Cue不应该影响角色的位移、攻击等。**_
|
||||
|
||||
第一条原则是所有类型游戏必须遵守的。
|
||||
|
||||
而第二条原则就见仁见智了,因为游戏类型和玩法决定了cue的影响范围。
|
||||
比如即时战斗类游戏,cue对角色位移有操作显然就是干涉了战斗,但如果是回合制游戏,cue对角色位移的操作就可以被当成是动画表现。
|
||||
(甚至,即便是即时战斗类游戏,cue对角色位移的操作也可以被当成是动画表现,只要游戏开发人员认为cue的位移操作不影响游戏的战斗结果即可。)
|
||||
|
||||
## GameplayCue的类型
|
||||
GameplayCue的类型分两大类:
|
||||
- GameplayCueInstant:瞬时性的Cue,比如播放动画,伤害UI提示等
|
||||
- GameplayCueDurational:持续性的Cue,比如持续性的特效、持续性的音效等
|
||||
|
||||
GameplayCueInstant和GameplayCueDurational都是抽象类,它们的子类才是真正的可使用Cue类。
|
||||
Cue是需要程序开发人员大量实现的,毕竟游戏不同导致游戏提示千变万化。
|
||||
|
||||
### 关于Cue的子类实现
|
||||
Cue的完整组成为GameplayCue和GameplayCueSpec:
|
||||
- GameplayCue< T >(抽象基类,T为对应的Spec类):Cue的数据实类,是一个可编辑类,开发人员可以在编辑器中设置Cue的各种参数。该类只可以被视作数据类。
|
||||
- 必须实现CreateSpec方法:用于创建对应的Spec类
|
||||
- GameplayCueSpec(抽象基类):Cue的规格类,是Runtime下Cue的真正实例,Cue的具体逻辑在该类中实现。
|
||||
- GameplayCueInstantSpec:瞬时性Cue的规格类
|
||||
- Trigger(): 必须实现的方法,用于触发Cue
|
||||
- GameplayCueDurationalSpec:持续性Cue的规格类
|
||||
- OnAdd(): 必须实现的方法,用于Cue被添加时的逻辑
|
||||
- OnRemove(): 必须实现的方法,用于Cue被移除时的逻辑
|
||||
- OnGameplayEffectActivated(): 必须实现的方法,用于Cue所属的GameplayEffect被激活时的逻辑
|
||||
- OnGameplayEffectDeactivated(): 必须实现的方法,用于Cue所属的GameplayEffect被移除时的逻辑
|
||||
- OnTick(): 必须实现的方法,用于Cue的每帧更新逻辑
|
||||
|
||||
### 关于Cue的参数传递
|
||||
目前EX-GAS的Cue参数传递非常简陋,依赖于结构体GameplayCueParameters,成员如下:
|
||||
- GameplayEffectSpec sourceGameplayEffectSpec:Cue所属的GameplayEffect实例(如果是GE触发)
|
||||
- AbilitySpec sourceAbilitySpec:Cue所属的Ability实例(如果是Ability触发)
|
||||
- object[] customArguments:自定义参数,不同于GameplayCue中的数据。
|
||||
customArguments是供程序开发人员在业务逻辑内自由传递参数的载体。
|
||||
>注意:customArguments是一个object数组,开发人员需要自己保证传递的参数类型正确,否则会导致运行时错误。
|
||||
customArguments是最暴力的设计,往后EX-GAS的Cue参数传递设计还会进行优化。
|
||||
## GameplayCue的使用
|
||||
GameplayCue的使用手段很多,最基础的是在GameplayEffect中使用,Cue最开始的设计基础也是依附于GameplayEffect。Ability也可以对Cue进行操作。
|
||||
|
||||
除此之外,Cue的使用不限制于EX-GAS的体系内。开发者可以在任何地方使用Cue,只要能获取到GameplayCue的资源实例并且遵守Cue的原则即可。
|
||||
|
||||
### 在GameplayEffect中使用Cue
|
||||
GameplayEffect中使用Cue会根据GameplayEffect执行策略产生变化。
|
||||
- 即时执行的GameplayEffect: 提供以下选项
|
||||
- CueOnExecute(Instant):Cue都会在GameplayEffect执行时触发。
|
||||
- 持续执行的GameplayEffect: 提供以下选项
|
||||
- CueDurational(Durational):生命周期完全和GameplayEffect同步
|
||||
- CueOnAdd(Instant):GameplayEffect添加时触发
|
||||
- CueOnRemove(Instant):GameplayEffect移除时触发
|
||||
- CueOnActivate(Instant):GameplayEffect激活时触发。
|
||||
- CueOnDeactivate(Instant):GameplayEffect失活时触发。
|
||||
|
||||
### 在Ability中使用Cue
|
||||
AbilityAsset中提供了Instant和Durational两个选项的Cue参数。
|
||||
但是Cue的使用完全依赖于Ability自身的业务逻辑,因此程序开发者在AbilitySpec中实现Cue逻辑时一定要保证合理性。
|
||||
特别是对于Durational类型的Cue,一定要保证Cue生命周期的合理性,切记不要出现遗漏销毁Cue的情况。
|
||||
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02b69f3c421280044b4707312c10498a
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,68 @@
|
||||
# EX-GAS Wiki -- GameplayEffect
|
||||
## GameplayEffect的作用
|
||||
GameplayEffect是EX-GAS的核心之一,一切的游戏数值体系交互基于GameplayEffect。
|
||||
|
||||
GameplayEffect掌握了游戏内元素的属性控制权。理论上,只有它可以对游戏内元素的属性进行修改
|
||||
(这里指的是修改,数值的初始化不算是修改)。当然,实际情况下,游戏开发人员当然可以手动直接修改属性值。
|
||||
但是还是希望游戏开发者尽可能的不要打破EX-GAS的数值体系逻辑,因为过多的额外操作可能会导致游戏的数值体系变得混乱,难以追踪数值变化等等。
|
||||
|
||||
另外GameplayEffect还可以触发Cue(游戏提示)完成游戏效果的表现,以及控制获取额外的能力等。
|
||||
|
||||
---
|
||||
> 由于GameplayEffect是被封装好的,程序开发者不会接触它的实现逻辑,所以本文Wiki将跳过对其接口以及代码逻辑的解析。
|
||||
> 后续,可能会完善代码接口的介绍。
|
||||
|
||||
# GameplayEffect的使用
|
||||

|
||||
|
||||
GameplayEffect的配置界面如图,接下来逐一解释各个参数的含义。
|
||||
- Name:GameplayEffect的名称,纯粹用于显示,不会影响游戏逻辑。方便编辑者区分GameplayEffect。
|
||||
- Description:GameplayEffect的描述,纯粹用于显示,不会影响游戏逻辑。方便编辑者阅读理解GameplayEffect。
|
||||
- DurationPolicy:GameplayEffect的执行策略,有以下几种:
|
||||
- Instant:即时执行,GameplayEffect被添加时立即执行,执行完毕后销毁自身。
|
||||
- Duration:持续执行,GameplayEffect被添加时立即执行,持续时间结束后移除自身。
|
||||
- Infinite:无限执行,GameplayEffect被添加时立即执行,执行完毕后不会移除,需要手动移除。
|
||||
- None:无效果,这是默认占位符,因为GameplayEffect是结构体,None方便视作GameplayEffect的空值。
|
||||
_**GameplayEffect配置的执行策略禁止使用None!!!**_
|
||||
- Duration:持续时间,只有DurationPolicy为Duration时有效。
|
||||
- Every(Period):周期,只有DurationPolicy为Duration或者Infinite时有效。每隔Period时间执行一次PeriodExecution。
|
||||
- PeriodExecution:周期执行的GameplayEffect,只有DurationPolicy为Duration或者Infinite,且Period>0时有效。每隔Period时间执行一次PeriodExecution。
|
||||
_**PeriodExecution禁止为空!!**_PeriodExecution原则上只允许是Instant类型的GameplayEffect。但如果根据开发者需求,也可以使用其他类型的GameplayEffect。
|
||||
- GrantedAbilities:授予的能力,只有DurationPolicy为Duration或者Infinite时有效。在GameplayEffect生命周期内,GameplayEffect的持有者会被授予这些能力。
|
||||
GameplayEffect被移除时,这些能力也会被移除。
|
||||
- Modifiers: 属性修改器。GameplayEffect的核心功能,用于修改GameplayEffect持有者的属性。
|
||||
- Attribute:属性名称,需要填写属性的全名,比如战斗属性集里的生命值:AS_Fight.Health
|
||||
- ModifierMagnitude:基础模值,这个模值是否使用依赖于MMC的类型。在中有Wiki-MMC详细介绍。
|
||||
- Operation:属性修改操作,有加法、乘法、赋值(覆写)等。
|
||||
- MMC:属性修改计算类,用于计算ModifierMagnitude的值。
|
||||
EX-GAS提供了多种ModifierCalculation,开发者也可以自定义ModifierCalculation。
|
||||
ModifierCalculation的类型在Wiki-MMC详细介绍。
|
||||
- Tags:标签。Tag具有非常重要的作用,合适的tag可以处理GameplayEffect之间复杂的关系。
|
||||
- AssetTags:描述性质的标签,用来描述GameplayEffect的特性表现,比如伤害、治疗、控制等。
|
||||
- GrantedTags:GameplayEffect的持有者会获得这些标签,GameplayEffect被移除时,这些标签也会被移除。
|
||||
Instant类型的GameplayEffect的GrantedTags是无效的。
|
||||
- ApplicationRequiredTags:GameplayEffect的目标单位必须拥有 **【所有】** 这些标签,否则GameplayEffect无法被施加到目标身上。
|
||||
- OngoingRequiredTags:GameplayEffect的目标单位必须拥有 **【所有】** 这些标签,否则GameplayEffect不会被激活(施加和激活是两个概念,
|
||||
如果已经被施加的GameplayEffect持续过程中,目标的tag变化了,不满足,效果就会失活;满足了,就会被激活)。
|
||||
Instant类型的GameplayEffect的OngoingRequiredTags是无效的。
|
||||
- RemoveGameplayEffectsWithTags:GameplayEffect的目标单位当前持有的所有GameplayEffect中,拥有 **【任意】** 这些标签的GameplayEffect会被移除。
|
||||
- Cues:GameplayEffect的提示。GameplayEffect可以触发Cue(游戏提示)完成游戏效果的表现,以及控制获取额外的能力等。
|
||||
- DurationPolicy为Instant时
|
||||
- CueOnExecute(Instant):GameplayEffect执行时触发。
|
||||
- DurationPolicy为Duration或者Infinite时
|
||||
- CueDurational(Durational):生命周期完全和GameplayEffect同步
|
||||
- CueOnAdd(Instant):GameplayEffect添加时触发
|
||||
- CueOnRemove(Instant):GameplayEffect移除时触发
|
||||
- CueOnActivate(Instant):GameplayEffect激活时触发。
|
||||
- CueOnDeactivate(Instant):GameplayEffect失活时触发。
|
||||
|
||||
## GameplayEffect的施加(Apply)和激活(Activate)
|
||||
GameplayEffect的施加(Apply)和激活(Activate)是两个概念,施加是指GameplayEffect被添加到目标身上,激活是指GameplayEffect实际生效。
|
||||
|
||||
为什么做区分?
|
||||
|
||||
举个例子:固有被动技能(Ability)是持续回血,被动技能的逻辑显然是永久激活的状态,而持续回血的效果(GameplayEffect)
|
||||
来源于被动技能,那如果单位受到了外部的debuff禁止所有的回血效果,那么是不是被动技能被禁止?显然不是,被动技能还是会持续激活的。
|
||||
那应该是移除回血效果吗?显然也不是,被动技能整个过程是不做任何变化,如果移除回血效果,那debuff一旦消失,谁再把回血效果加回来?
|
||||
所以,这里需要区分施加和激活,被动技能的持续回血效果被施加到单位身上,而debuff做的是让回血效果失活,而不是移除回血效果,一旦debuff结束,
|
||||
回血效果又被激活,而这个激活的操作可以理解为回血效果自己激活的(依赖于Tag系统)。
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2b6db06b286851419fb59afd740df3e
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa26d750811c9a44f88f4e478131110e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
@@ -0,0 +1,109 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4500fcbdf9ac27349a9c61c6bfd44ab7
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
@@ -0,0 +1,109 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dced26454ba437409e9dae9ac404b54
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
44
JNFrame2/Assets/HotScripts/JNGame/Runtime/GAS/Wiki/MMC.md
Normal file
44
JNFrame2/Assets/HotScripts/JNGame/Runtime/GAS/Wiki/MMC.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# EX-GAS Wiki -- MMC(Modifier Magnitude Calculation)
|
||||
## MMC的作用
|
||||
MMC(Modifier Magnitude Calculation)是一个用于计算Modifier的模值的可编辑类,它的作用是根据输入的参数计算Modifier的模值,然后在后续逻辑中将模值赋给对应的属性。
|
||||
## MMC的使用
|
||||
在EX-GAS中MMC只会在GameplayEffect中使用。
|
||||
|
||||
MMC依存于GameplayEffectModifier中,GameplayEffectModifier是包裹MMC的结构体,MMC为GameplayEffectModifier成员之一。
|
||||
GameplayEffectModifier为GameplayEffect的成员之一。
|
||||
|
||||
**GameplayEffectModifier在EX-GAS中非常重要,它是GAS属性变化的核心,所有的游戏运行时的元素属性变化全部由他操作(除了属性初始化,或者开发人员手动设置属性值的情况)。**
|
||||
|
||||
GameplayEffectModifier成员组成(所有成员都需要在编辑器中设置):
|
||||
- AttributeName:Modifier作用的属性名称,一个游戏效果对一个元素属性产生影响时,需要表明影响哪个属性
|
||||
- ModiferMagnitude:基础模值,这个模值是否使用依赖于MMC的类型。后文MMC的类型中会详细介绍。
|
||||
- Operation:Modifier的操作类型,有加法、乘法、赋值(覆写)等
|
||||
- MMC:计算Modifier模值的计算类,后文MMC的类型中会详细介绍
|
||||
```
|
||||
例子:伤害效果,对单位造成50点伤害
|
||||
GameplayEffectModifier:
|
||||
AttributeName:AS_Fight.Health
|
||||
ModifierMagnitude:50
|
||||
Operation:Add
|
||||
MMC:ScalableFloatModCalculation -> k=-1,b=0 (下文会介绍ScalableFloatModCalculation的k,b含义)
|
||||
```
|
||||
|
||||
## MMC的类型
|
||||
MMC的基类为抽象类ModifierMagnitudeCalculation,它的子类有以下几种:
|
||||
- ScalableFloatModCalculation:可缩放浮点数计算
|
||||
- 该类型是根据ModifierMagnitude计算Modifier模值的,计算公式为:`ModifierMagnitude * k + b`
|
||||
实际上就是一个线性函数,k和b为可编辑参数,可以在编辑器中设置。
|
||||
- AttributeBasedModCalculation:基于属性的计算
|
||||
- 该类型是根据属性值计算Modifier模值的,计算公式为:`AttributeValue * k + b`
|
||||
计算逻辑与ScalableFloatModCalculation一致。
|
||||
- 重点在于属性值的来源,确定属性值来源的参数有3个:
|
||||
- attributeFromType:属性值从谁身上取?是从游戏效果的来源(创建者),还是目标(拥有者)。
|
||||
- attributeName:属性值的名称,比如战斗属性集里的生命值:AS_Fight.Health
|
||||
- captureType:属性值的捕获类型
|
||||
- Track: 追踪,在Modifier被执行时,当场去取属性值
|
||||
- SnapShot: 快照,在游戏效果被创建时会对来源和目标的属性进行快照。在Modifier被执行时,去取快照的属性值。
|
||||
- SetByCallerModCalculation:由调用者设置的计算
|
||||
- 不使用任何值计算模值,而是在执行时由调用者给出Modifier模值。
|
||||
- CustomCalculation:自定义计算(必须继承自抽象基类ModifierMagnitudeCalculation)
|
||||
- 上述3种类型显然不够方便且全面的满足游戏开发者的所有需求,所以提供了自定义计算类的功能。
|
||||
- 允许开发者自由发挥给出各种各样的计算逻辑。
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36f0dd248cec13a42b86e265c8eaff2f
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user