找回密码
 点一下
查看: 1819|回复: 14

關於Marker 的研究心得與觀念釐清

[复制链接]
发表于 2013-8-1 10:35:25 | 显示全部楼层 |阅读模式
本帖最后由 playif 于 2013-8-1 12:13 编辑

最近研究了一下Marker的使用方式,感覺網路上的資料大多不全,只教你怎麼套著用,對於要自己創造複雜技能的幫助還是有限。於是自己做了點研究,並將心得分享出來。

閱讀本文需對於Data 有基本了解,而且本文有許多假設是根據Try&Error得出,有不懂或是發現錯誤的地方歡迎交流。


先說一下Marker的功能吧,主要限制一次的施放(技能,武器或效果)中,每個目標受到影響的次數。限制的方式就是透過Validator中的Marker count 來指定。


但是具體是怎麼運作?幾乎每個effect,effect ability , weapon 都可以指定marker。還有marker本身又有許多子欄位,但Valodator 卻只能比較數量。


事實上具體的運作方式只有官方自己才會知道,在沒有文件的情況下,我經過測試後自行推測其運作機制如下:
假設1. marker 是標記在單位身上,並且有一個特定的生命週期。
這比較容易理解,我們就是在unit 上打一個marker,避免他被重複計算傷害,而且marker一定有結束的時候,否則照理說整場遊戲只會被傷害一次。
然而,這個週期似乎又不是以一次的攻擊(或技能)來決定,設定Marker 的位置(在整個effect鏈)似乎又會左右其結果。於是我們需要更多假設。


假設2. marker 的生命週期取決於設定marker 的effect,而effect週期的結束則代表該effect的所有子節點effect 都執行完。
什麼意思呢?假設你現在有一個週期性的effect (persistent),每次週期發動一個傷害effect。那marker 和驗證器(validator) 分別該放在哪裡?
有經驗的人一下就知道:在週期性effect 設定marker,在傷害effect 設定validator。但是...why?為了解釋這一問題,我又做了如下假設。


假設3. marker 的設定只決定其生命週期,並不一定會馬上套用marker 到單位身上 (至於到底會不會請看假設5)。
(先釐清一下,"套用marker"指的是marker count 真的會+1的時機,是在遊戲中才會發生; 而"設定marker"指的是你在data 中設定marker的欄位)
這樣想就說的通了,以上面的那問題為例,在週期性effect 設定marker只是先宣告之後的effect會套用該marker到單位身上。實際會增加marker 的時間點是在傷害的effect。這同時也說明了為何只在傷害effect 設定marker會導致整個驗證失效,因為每次傷害一結束(其實是一瞬間的事),marker的生命週期也跟著結束,下次的傷害(雖然是透過週期effect發動,例屬於同一次發動的攻擊/技能) ,但仍然沒有marker在目標身上。
好,看到這裡你可能會想,那如果我在週期effect 和傷害effect都設定marker,那會怎樣呢? 經過幾個實驗,我又做了一個假設如下。

假設4. 驗正器只會比較最接近於驗正器位置的marker。
也就是傷害effect所設置的marker,因此會造成結果跟只在傷害effect設置marker 一樣。
那原本週期effect的marker呢?也還是在,但是因為驗正器的位置在傷害effect 那邊,所以就被蓋掉了兒已。
這道理有點像程式的變數,scope不一樣但變數名稱一樣的時候,越接近(越小)的scope的變數會被優先使用。

其實說穿了,就是marker最好是在週期effect 那裡,然後在之後的effect 都不要設定。好啦,如果只寫到這裡,你可能會覺得廢話一堆結論卻是個屁!
到底知道上面的假設有什麼幫助呢? 其實這只是基礎而已,還有幾個問題要繼續釐清,才有辦法真正應用marker。

假設5. 不是每個effect 都會套用marker到單位身上,即使在其父結點effect 已經設定過marker。
我可以肯定的是,傷害effect和modify unit effect會套用marker。而像週期effect,search area effect,set effect等則不會。我推測是有明確target unit 才有機會基會套用marker,然而像是create unit effect 這類的也不行(我推測是要直接對target 有影響的才行)。另外,比較奇怪的是指定單位的技能會直接套用marker,而weapon則不會直接套用。

好,到這裡事情逐漸明朗了,我想說的是,marker最好只設定一次(在整個effect 鏈中),並且越接近整個effect鏈的起點越不會出錯,驗正器則放在你真正想限制是否執行的effect上。如果你想要用一些奇奇怪怪的特效,或是靠驗證器做出迴圈的效果,可以用個零傷害或無修改的effect來標記單位,配合set effect 來達到你的目的。

舉個例子,我就直接說我做了甚麼吧(這也是我研究marker,和這篇文章誕生的關係),一個不靠behavior的連鎖生成小狗的技能。所謂"連鎖"就是像連鎖閃電一樣,對於每個敵人的旁邊都產生一隻小狗,產生過小狗的敵人身邊不會重複產生,總共產生小狗的上限在驗證器裡決定(這樣一來只要改變驗正器裡的數字就可已決定總共要產生幾隻小狗)。

整個effect 鏈如下圖,將marker設定在最左邊的initial effect (一個只執行一次的週期effect),然後執行一個set effect,裡需要兩個驗正器(一個目標一個施法者),目標驗證器的上限是1,施法者驗正器的上限看你想總共產生幾知小狗(施法者的驗正器要改unit 欄位為caster)。另外需要一個產生小狗的effect,兩個"無修改"effect(目標跟師法者各套一個,施法者那個要改impact unit 欄位為caster),一個週期effect(為了delay用)。然後週期effect執行搜尋effect(可以設定排序找最接近的單位),只找一個為上限,就再執行set effect (也就是圖中最下面那條怪怪的線,靠他實現了迴圈,終止條件則靠驗證器控制,要注意marker的設定要在迴圈的外層,理由前面提過,所以才需要最左邊那個initial effect)。
擷取.PNG


最後的最後,一直提到設定marker,但marker 到底要怎麼設定?
首先,link欄位跟底下match flags 的link 有關(也就是如果你下面沒有勾選link,那上面的link 也不用設定了)。
count數一般設為1就好,就是套用一次marker 實際增加的次數。
右下的mismatch flags 可以忽略了,幾乎用不到。
剩下的match flags (原則上四選一就好,複選的話就是邏輯且的運算):
casting player: 同一個玩家不會重複對目標造成傷害,對於你有兩個以上的施法者,而且要在設定marker 的effect 結束前才有效(簡而言之如果沒有週期性之類的effect 的話其實marker 幾乎都拍不上用場,不然就要剛好同時發動)。
casting unit: 同一個單位不會重複對目標造成傷害,對於你有一個單位擁有兩個一樣的技能(或因為CD很短讓你可以在effect結束前施放兩次該技能),其他同上。
casting id: 同一次施放技能/武器/效果,不會重複對目標造成傷害,其他同上。基本上沒有特殊理由的話,勾這個就好,比較不會有問題。
Link: 同一個effect/ability/weapon 不會重複對目標造成傷害,其他同上。基本上這個可以配合casting player,不然範圍有點太大,除非你想做類似無差別攻擊之類的marker。


總算完成了~注意一下,之所以說假設就是不確定,只是我盡可能的實驗過各種情況得出的結論而已。歡迎交流。

補充:
看了頭目提示的連結:
http://bbs.islga.org/forum.php?m ... 74013&fromuid=3

裡面提問者問到這個效果:
發射8個光束,平均攻擊附近的單位。
有8個單位就每人打一下,2個單位就每人4下,1個單位就8下全中。
是靠目標排序實現的吧?


我嘗試用文章提到的概念和我自己的理解來實現,
用了三個effect,整個鏈如下:
週期 Effect --> search area effect --> 傷害 effect
代碼如下:

週期 Effect: 週期設8次,設定marker。 (可以在這裡設定時間間格)
  1.     <CEffectCreatePersistent id="HitInitial">
  2.         <EditorCategories value=""/>
  3.         <PeriodCount value="8"/>
  4.         <PeriodicEffectArray value="HitSearch"/>
  5.         <Marker Link="">
  6.             <MatchFlags index="Id" value="1"/>
  7.         </Marker>
  8.     </CEffectCreatePersistent>
复制代码
search area effect: 以marker 排序,以自己為中心(CenterAtLaunch)
  1.     <CEffectEnumArea id="HitSearch">
  2.         <EditorCategories value=""/>
  3.         <SearchFilters value="-;Self,Player,Ally,Neutral,Missile,Item,Cloaked,Dead"/>
  4.         <TargetSorts>
  5.             <SortArray value="TSMarker"/>
  6.         </TargetSorts>
  7.         <AreaArray MaxCount="1" Radius="5" Effect="HitDamage"/>
  8.         <SearchFlags index="CenterAtLaunch" value="1"/>
  9.         <SearchFlags index="OffsetAreaByAngle" value="0"/>
  10.     </CEffectEnumArea>
复制代码
傷害effect 沒啥好說的~
  1.     <CEffectDamage id="HitDamage">
  2.         <EditorCategories value=""/>
  3.         <Amount value="5"/>
  4.     </CEffectDamage>
复制代码
居然就成功了~~ (頗有成就感XD)
擷取.PNG
发表于 2013-8-1 10:43:56 | 显示全部楼层
http://bbs.islga.org/forum.php?m ... 74013&fromuid=3
这里有群里我对这个东西的一些解说,从地板楼开始看就是了

点评

感謝~~馬上來研就一下!!  详情 回复 发表于 2013-8-1 10:47
回复 1 0

使用道具 举报

发表于 2013-8-1 10:46:33 | 显示全部楼层
Marker一下,很有用的东西。

点评

歡迎指教~~ 我也還在摸索中~~ 順便把自己的一點心得整裡一下~~  详情 回复 发表于 2013-8-1 11:32
回复

使用道具 举报

发表于 2013-8-1 10:47:31 | 显示全部楼层
其实Data Editor里面Marker的相关设置项不是很直观易用。

实际上应该专门给Marker设置一页的

回复

使用道具 举报

 楼主| 发表于 2013-8-1 10:47:46 | 显示全部楼层
回复

使用道具 举报

 楼主| 发表于 2013-8-1 11:32:31 | 显示全部楼层
『四裤全输』 发表于 2013-8-1 10:46
Marker一下,很有用的东西。

歡迎指教~~
我也還在摸索中~~ 順便把自己的一點心得整裡一下~~

点评

不过我发的那个帖子里的内容比较早,不确定这个系统是否有改变过。  详情 回复 发表于 2013-8-1 15:21
回复

使用道具 举报

发表于 2013-8-1 15:19:44 | 显示全部楼层
没用过marker,貌似在使用触发器和使用界面修改数据时都不会碰到。
看了楼主和各位的说明后,自己也想到些东西。。

依据楼主的分析,我感觉marker这东西应该属于游戏运算期间的数据标识逻辑的部分,这东西只是一种从属于某个主体的逻辑数据,讨论它自身的生命周期没什么意义。顾名思义"marker"就是"标记"的意思。但实际上一个标记到底发挥什么作用,得看使用者的逻辑。

例如
(1)医疗技能,一个单位同一时间只会受到一个医疗效果。这里,匹配器只会匹配marker中"效果名"这部分,并过滤已拥有改效果名的单位
(2)坦克的溅射伤害,多个坦克可以伤害同一个单位,但不会重复伤害。这里,匹配器至少会匹配marker中的"效果名"和"释放者"这两部分的数据,并过滤已拥有匹配上的单位。

对于生命周期,marker作为一个从属逻辑,我认为它由它的父对象管理。这个父对象可能是效果(effect),或者其它使用到marker的数据对象。当父对象销毁(结束)时,它按照自身逻辑去销毁(消除)它所产生的marker。

例如
(1)持续性伤害效果会在时间开始时标记上自己的marker,在时间结束后,它就应该没有任何作用了,所以它需要在结束时销毁自身和自身产生的marker。
(2)坦克变形效果会给单位加marker,然后变形结束时消去。
(3)瞬间伤害效果可能也有marker,毕竟看起来是瞬间,但游戏运行逻辑里,它可能不是一次性计算完成的,所以需要marker来避免一些情况。

总结下自己的观点,marker作为一种数据资源,用于标识有一定持续时间的数据行为。它的生命周期由产生它的父对象的逻辑决定。它的作用由读取它的数据对象的逻辑决定。它的自身是一连串的ID,从释放者到被作用对象到效果名字都可能记录在里面,用于各种情况的数据匹配。这是BZ的数据对象,到底以后会不会有改动得BZ说了算,但感觉大体设计逻辑就是这样,一般数据逻辑不会有太大改动。

回复 1 0

使用道具 举报

发表于 2013-8-1 15:21:18 | 显示全部楼层
playif 发表于 2013-8-1 11:32
歡迎指教~~
我也還在摸索中~~ 順便把自己的一點心得整裡一下~~

不过我发的那个帖子里的内容比较早,不确定这个系统是否有改变过。
回复

使用道具 举报

发表于 2013-8-1 19:00:35 | 显示全部楼层
我觉得可以用"染色"这个词来描述Marker.
回复

使用道具 举报

发表于 2013-12-12 17:29:44 | 显示全部楼层
仔细揣摩了这个贴以及贴中链接的聊天贴等有关内容后,尝试整理一下对Marker的看法

首先,所有能设置marker的数据类型(即父对象),不管是abli还是effect,提供的选项包括Casting Player, Casting Unit, Id, Link这四项,这四项对应的都是marker的属性,或者说,每一个完整的marker由这四个属性构成。
Casting Player: 该数据的所属玩家
Casting Unit: 该数据的所属单位
Link:可以理解为marker的名称
ID:marker的唯一识别标记

这里Link的意义是困扰我最久的一个问题,一直以来我都以为它是对应数据项的链接,但其实这是错误的,Link只是一个单纯的字符串,内容看起来像数据项链接只是为了更好的识别这个Link。Link和ID的关系,说白了就好像新建任意一个新数据需要确定的Name和ID的关系一样。

而Casting Player和Casting Unit这两项则唯一确定了marker的父对象。更通俗的说法就是每一个effect或者abli都有唯一的所属单位和所属玩家,一旦确定了所属单位和所属玩家,就可以准确指定对应的这个effect/abli,类似在二维坐标系中通过x和y坐标确定一个点一样。

所以,一个marker=一个确定的父对象(由Casting Player和Casting Unit确定)施加在作用对象的同时加上的标记,这个标记有名字(Link),标记与标记可以有相同的名字,但每个标记都有唯一的ID。

其次,在marker的设置中还分为match和mismatch两个部分。通过分别在这两个部分中确定选项,结果是制定了一个关于marker的匹配规则集。制定规则的目的是为了计算marker数量,并和相关的validator结合起来,作为某个数据是否生效的判断条件。这么说有些抽象,还是举个例子。

比方说,技能A的marker设置为:

match: Link
mismatch: ID

(实际上所有类型为effect-target的技能marker的默认设置都是这样)

假设这个技能其中一个damage effect的验证器为No Markers,也即marker数量为0。各位应该都知道验证器的作用,它表示这个damage effect生效的前提是目标的marker数量为0 。关键的问题来了,这个marker数量是如何确定的? 答案就是之前那个match和mismatch的内容。

match:Link的意义在于要求marker的Link,也就是名字要一样;mismatch:ID的意义在于要求marker的ID要不一样,也就是不能是同一个marker。对比的双方就是技能A确定的marker,和目标身上已有的每一个marker。

技能A的marker= 技能A的所属玩家(Casting Player)+技能A的所属单位(Casting Unit)+技能A的名称(Link)+ID

而目标身上可能有非常多的marker,真正能算数的,只有名称一样(match: Link),而且ID不一样(mismatch: ID,即并非同一个marker)的那些marker。如果目标身上一个符合条件的marker都没有,则marker数量为0,noMarkers这个验证器验证通过,damage effect可以施放于目标,反之亦然。

最后,关于marker的生命周期。marker随父对象的产生而产生,随父对象的销毁而销毁。对于damage effect这种一次性的效果来说,marker被瞬间的创建又被瞬间的销毁;对于Create Persistant这种持续性效果来说,marker会一直存在直到效果结束。

结尾就运输机治疗技能和雷诺的狙击枪技能实际分析一下,这两个技能都在实际作用的effect中加上了noMarkers的验证器。

治疗技能的marker设置与上面所举的技能A一致,那么

当运输机A准备向给目标施放heal effect的时候(假设目标并未接受其他治疗),显然是可以生效的,因为目标身上一个marker也没有,验证器取到的marker数量为0;
当运输机A开始给目标施放heal effect的同时,就在目标身上放下了对应的marker;
当运输机A结束对目标的治疗的时候,之前放下的marker也被销毁。

当运输机A正在对目标治疗的同时,如果运输机B也准备给目标施放heal effect,验证器首先会去取目标身上有几个符合条件的marker,结果运输机A放在目标身上的marker符合条件(名称一样,ID不一样),marker数量为1,所以无法通过nomarkers这个验证器,运输机B无法对该目标进行治疗。

狙击技能的Create Persistent effect设置了额外的marker匹配条件

match: ID

意思就是相同的marker视为符合计算条件的marker。这个周期性effect包含多次搜索effect,可以理解为每次搜到一个单位并施放damage的时候,就给这个单位加上marker,那么

当第一次搜到目标A的时候,就给A加上marker并附加伤害damage;
当第二次搜到目标A的时候,因为A身上已经有了一个一样的marker,所以marker的数量为1,noMarkers验证器验证失败,无法再次附加伤害damage。

这样就避免了一次施放技能对同一个目标造成多次伤害,需要注意的是,由周期性effect施放在单位上的marker要在这个周期性effect结束时才会销毁,因此在同一个周期性effect的多次搜索effect期间目标身上一直会带有marker。

另外对于marker我还有一点疑问,希望有人能解答:

根据狙击技能的效果,周期性effect的marker的应该是在通过了damage effect的验证器之后才加到目标上的。如果是这样的话,那么把验证器移到搜索effect上应该能实现同样的效果,但实际上如果这样做的话,没有damage effect会生效,这意味着搜索effect无法搜索到任何符合条件的单位,也就说明在搜索的时候单位身上已经带有周期性effect了,但这又如何解释一个已经带有marker的单位可以通过damage effect的验证器?

不同类型的marker施放在目标身上的准确时间点究竟是啥?
validator会进行比较的是不是包括父对象上下游所有对象的marker?

点评

今晚刚好路过,看到就顺便回一下自己的想法。一搞就2个小时,都快2点了,发完就睡觉 首先,我感觉link不是name那么简单。我搞过编程,如果只是名字(name)那么程序员会用name而不是link.用link的意思是连接  详情 回复 发表于 2013-12-13 01:37
回复

使用道具 举报

发表于 2013-12-13 01:37:33 | 显示全部楼层
本帖最后由 ff1407 于 2013-12-13 01:40 编辑
captainthief 发表于 2013-12-12 17:29
仔细揣摩了这个贴以及贴中链接的聊天贴等有关内容后,尝试整理一下对Marker的看法

首先,所有能设置mark ...

今晚刚好路过,看到就顺便回一下自己的想法。一搞就2个小时,都快2点了,发完就睡觉

首先,我感觉link不是name那么简单。我搞过编程,如果只是名字(name)那么程序员会用name而不是link.用link的意思是连接,也就是这个marker到底连接到一个什么东西上。我没仔细研究过,但有可能这个游戏逻辑能通过link这串字符进行二次搜索,从而获得更多数据信息。这东西可能已经实现,或者是为将来扩展的一个设计。

接着,对于你最后的问题。我研究得出的结论有两个:
(1) 编辑器使用期间隐藏了验证器的对象信息。伤害效果运行验证器时会用目标单位验证,但搜索效果运行验证器时用的是搜索位置的方位坐标点。于是乎绝对没有一个坐标点能通过nomarker验证。你可以看看附件里我添加的距离验证器就生效了
(2) 关于的添加问题。我的结论暂时是marker跟随行为(behavior)添加。狙击技能的Create Persistent effect设置了marker的添加效果,然后在(apply behavior)的行为里添加进单位。我把效果集里的Damage和Apply Behavior两个效果顺序反过来后,伤害效果的nomarkers验证一个都不通过。原来是先伤害再添加marker来防止重复伤害,反过来后先添加marker再验证肯定通不过。



test006.SC2Map

26.38 KB, 下载次数: 3

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-24 11:46 , Processed in 0.385607 second(s), 34 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表