请选择 进入手机版 | 继续访问电脑版

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

修改数据模板是延时生效的?

[复制链接]
发表于 2016-12-20 00:27:55 | 显示全部楼层 |阅读模式
1.SC2Map (11.77 KB, 下载次数: 4)
如测试图,我想在机枪兵开枪后动态修改伤害,于是在伤害效果前加了一个效果,当该效果发生时修改数据模板。
预想结果:机枪兵直接攻击一下,伤害是10,使用一个技能给自己添加个空buff后,再次攻击,伤害会变20。
然而事实证明,该效果发生后,必须要等待大于0.0625秒才能调用伤害效果,否则修改不会在当前效果树下生效,必须要等下次攻击才有效。
比如直接调用伤害效果而无延时的话,第一次攻击显示为6(修改前的值),再次攻击伤害是10,使用技能后攻击,伤害仍是10,再次攻击伤害变20。
我想请问大家,你们修改数据模板没有遇到这个问题么?如果有演示,那么修改数据模板的功能就没有什么实质性作用了。
发表于 2016-12-20 07:08:23 | 显示全部楼层
你这结论完全错误。

这里的原因仅仅是触发器响应事件的时候都是在周期末尾进行的而已。所以这时候同一个周期内所有的效果都已近执行完了。除非是由触发器来引发的效果。你这个设计本身就是错的。



游戏实际运作的时候是这样的,在同一个周期内。

执行效果A
执行效果B
执行效果C
引发效果A被执行事件
引发效果B被执行事件
引发效果B被执行事件


中间没有任何等待。以及修改数据模版没有任何生效延迟。


另外“没有什么实质性作用”这种论调真是,怎么说呢?真是缺乏想象力啊。


回复

使用道具 举报

发表于 2016-12-20 08:47:02 | 显示全部楼层
修改数据模板与制造伤害效果,必须都在触发器里执行才能使用这种办法的。

因为数据层执行先于触发器层,头目说的很清楚了已经。

点评

但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会生效,这样无需等待或者仅等到小于一个周期的时间即可。然而实测结果却不是,必须要在下下个周期才行,也就是  详情 回复 发表于 2016-12-20 14:21
但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会生效,这样无需等待或者仅等到小于一个周期的时间即可。然而实测结果却不是,必须要在下下个周期才行,也就是  详情 回复 发表于 2016-12-20 14:21
但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会生效,这样无需等待或者仅等到小于一个周期的时间即可。然而实测结果却不是,必须要在下下个周期才行,也就是  详情 回复 发表于 2016-12-20 14:21
回复

使用道具 举报

 楼主| 发表于 2016-12-20 14:20:58 | 显示全部楼层
东方油瓶 发表于 2016-12-20 08:47
修改数据模板与制造伤害效果,必须都在触发器里执行才能使用这种办法的。

因为数据层执行先于触发器层, ...

但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会生效,这样无需等待或者仅等到小于一个周期的时间即可。然而实测结果却不是,必须要在下下个周期才行,也就是说,延时必须要超过0.0625秒。
这一点想好久也不是很明白。
回复

使用道具 举报

 楼主| 发表于 2016-12-20 14:21:06 | 显示全部楼层
东方油瓶 发表于 2016-12-20 08:47
修改数据模板与制造伤害效果,必须都在触发器里执行才能使用这种办法的。

因为数据层执行先于触发器层, ...

但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会生效,这样无需等待或者仅等到小于一个周期的时间即可。然而实测结果却不是,必须要在下下个周期才行,也就是说,延时必须要超过0.0625秒。
这一点想好久也不是很明白。
回复

使用道具 举报

 楼主| 发表于 2016-12-20 14:21:07 | 显示全部楼层
东方油瓶 发表于 2016-12-20 08:47
修改数据模板与制造伤害效果,必须都在触发器里执行才能使用这种办法的。

因为数据层执行先于触发器层, ...

但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会生效,这样无需等待或者仅等到小于一个周期的时间即可。然而实测结果却不是,必须要在下下个周期才行,也就是说,延时必须要超过0.0625秒。
这一点想好久也不是很明白。
回复

使用道具 举报

 楼主| 发表于 2016-12-20 14:21:15 | 显示全部楼层
东方油瓶 发表于 2016-12-20 08:47
修改数据模板与制造伤害效果,必须都在触发器里执行才能使用这种办法的。

因为数据层执行先于触发器层, ...

但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会生效,这样无需等待或者仅等到小于一个周期的时间即可。然而实测结果却不是,必须要在下下个周期才行,也就是说,延时必须要超过0.0625秒。
这一点想好久也不是很明白。

点评

星际 2 最小时间间隔是0.0625秒啊。 数据层等待0.0625,这个时候触发器刚刚跑完,还没有进入下一个周期。 仅仅是个人的猜测。 关于这个0.0625与游戏速度也是有一些奇怪的设定的。 比如无论游戏速度 更慢还  详情 回复 发表于 2016-12-20 17:36
回复

使用道具 举报

发表于 2016-12-20 17:36:59 | 显示全部楼层
yxxiaobin 发表于 2016-12-20 14:21
但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会 ...

星际 2 最小时间间隔是0.0625秒啊。

数据层等待0.0625,这个时候触发器刚刚跑完,还没有进入下一个周期。

仅仅是个人的猜测。

关于这个0.0625与游戏速度也是有一些奇怪的设定的。
比如无论游戏速度 更慢还是更快,最小的时间永远都是 游戏时间为单位的 0.0625.
坦率的说...有点古怪。
回复

使用道具 举报

发表于 2016-12-20 18:09:00 | 显示全部楼层
yxxiaobin 发表于 2016-12-20 14:21
但不明白为何必须等待超过0.0625秒。如果在一个周期的结束触发事件,然后修改模板,那么在下一个周期就会 ...

这什么话啊?你知道一个周期是多长时间吗?

你知道等待这个动作最短可以等待多久吗?
回复

使用道具 举报

 楼主| 发表于 2016-12-20 23:19:11 | 显示全部楼层
本帖最后由 yxxiaobin 于 2016-12-20 23:29 编辑

一般来说一个周期是0.0625秒吧。触发器等待的最短时间也是0.0625秒,而且只能是它的整数倍,除了0秒。实测零秒使用偶数次时会真的变成0秒,而奇数倍则是0.0625秒。不过我这里所说的延时并不是触发器,而是数据系统,我使用了创建持续性效果来延时启用效果。
我在想,假设延时0.0625秒。如果是一个周期末触发事件,修改了模板,那怕效果是在周期初发生的,那么等伤害效果调用时也过了0.0625秒,实际上就到了下个周期了,而这时模板已经在上个周期被修改了,就应该使用新的数值才对。如图所示:
1.png

但实测结果是依旧使用旧值。只有延时大于0.0625秒时才能正确生效。那怕是0.07秒也行。可是根据图示看的话,及时伤害效果向后移一小段时间,也未必会移出周期。
如果要出现这种结果,只能是:游戏周期并不区分更细的时刻,认为所有的效果均在上个周期结束而下个周起开始时发生,而不是玩家操作它实际发生的时刻,这样等待一个周期,正好是周期末,和触发器修改模板属于同一时刻,而且模板数据是需要反复提取而不是一直生效的。因为一个周期只提取一次模板,在修改之前提取模板数据的话,及时修改了模板,也不会再当时就被使用,所以才会有这种情况。如下图所示:
1.png
开始并不这么理解,是我一直以为,在数据系统里边,0.06秒和0.05秒是不同的(并不是说运算是实时的,而是我以为尽管他们在同一时刻被运算,但是也会比对数值,这一点并不困难),比如同一集合里给单位一个行为,存在0.06秒,在持续性效果延时0.05秒后测试行为是否存在,应该返回存在。然而今天实际测试了一下,不是这样的,只要行为消失和效果验证在同一周期或更早消失,结果都是不存在,无论行为持续时间是否比要过延时长。所以可以知道,数据系统其实并不比对数据模板的数值,而是在需要比对时,直接探测单位是否带着行为就行了。
根据以上的测试结果可以知道:系统认为所有的事都是在同一时刻发生的,即上个周期结束,而下个周期开始时,而运算当然也是这时进行的。但是基于现实世界并不存在“同时”这种事,所以他们实际上是排队进行的。顺序为:首先取模板数据,然后处理触发器系统,然后处理行为系统,最后才是效果系统(仅讨论这四种数据的处理)。只有这样理解,才能解释上述测试结果。
第一项测试:
当第一周期开始时,没有触发器需要处理,直接处理效果。第二周期开始时,先取模板数据,这个数据显然是未经修改的。然后处理触发器,修改模板,但是这个模板值必须等个周期才会起效,因为模板数据已经被取过了,即使修改,系统也不会当即使用。接着处理效果系统,如果等待时间小于等于一个周期,伤害效果会发生,这就导致伤害使用了旧值。可是如果等待时间超过一个周期,此时并不处理伤害效果,需要等下个周期才处理,此时重新取模板数据,然后在发生伤害效果,这样就是更新后的值了。
第二项测试:
同理,当周期开始时,先处理行为数据,发现行为过期,予以删除。然后处理效果数据,发现没有行为,于是就认定单位在效果探测是并不存在行为,尽管我们指定了行为存在0.06秒而效果是在0.05秒时探测的,实际情况他们都在0.0625秒时发生,且行为优于效果。
附上测试图: 1.SC2Map (9.33 KB, 下载次数: 0)

以前有错误理解,一个很重要的原因是没有真正认识周期的意义,机械性的割裂周期,理解成某些事在周期开始做,然后等待一个周期,在周期结束时再做一些事。如图:
2.png
但显然,这种理解是错误的,或者是不好的,最佳的理解即:上一个周期的结束也是下一个周期的开始,依次做了一些事,然后等待一个周期。
2.png


回复

使用道具 举报

发表于 2016-12-21 12:10:39 | 显示全部楼层
其实最简单的验证方法:

用触发器直接修改一个伤害效果的模版,然后立即用触发器来执行这个效果。然后看造成多少伤害就能知道了。

顺便还可以看看伤害事件发生时和执行伤害效果动作时,游戏分别所输出的时间。

点评

用触发器来调用效果,让玩家施加给单位会使用新值。 输出时间证实:效果发生后一个周期的时间才会触发效果事件,这样基本上认为:触发器的处理优先度优于效果,所以效果发生时才不会立即触发事件。截图如下:[attac  详情 回复 发表于 2016-12-21 22:47
回复

使用道具 举报

发表于 2016-12-21 19:53:58 | 显示全部楼层
本帖最后由 疯人¢衰人 于 2016-12-21 20:15 编辑

这里其实的关键点在于触发和数据执行的连续关系,间隔最小是1/16(演算体是1/32用于平滑显示效果),
首先执行的是各种效果,每个效果的执行结果如果会引发触发的话,那么把对应的触发加入队列。如果执行的效果有伤害响应,这时伤害响应的触发会立即响应而不加入队列(类似中断的效果)
当效果全部执行完毕,开始执行触发,属性应该是按照队列的。触发完毕之后等待1/16,然后开始下一帧处理。

所以如果你修改数据模板,然后修改的效果是通过数据再次执行,那么就是下一帧了。
如果是通过触发执行,那么就是立即,所以处理的方法是修改数据模板之后用触发释放效果。
这里的缺点是效果树会被中断。


点评

确实使用触发器的话会出现不同的结果,我以上的测试仅针对使用数据的情况。 不过就我测试的结果我觉得,在处理数据时,应当是先取模板数据,然后处理触发器数据,此后才是行为和效果数据。 我也考虑过是不是先处理  详情 回复 发表于 2016-12-21 21:45
回复

使用道具 举报

 楼主| 发表于 2016-12-21 21:45:04 | 显示全部楼层
疯人¢衰人 发表于 2016-12-21 19:53
这里其实的关键点在于触发和数据执行的连续关系,间隔最小是1/16(演算体是1/32用于平滑显示效果),
首先 ...

确实使用触发器的话会出现不同的结果,我以上的测试仅针对使用数据的情况。
不过就我测试的结果我觉得,在处理数据时,应当是先取模板数据,然后处理触发器数据,此后才是行为和效果数据。
我也考虑过是不是先处理行为和效果数据,然后是触发器数据,这样就不需要有一个取模板数据的过程。但是后来想到,假如是这样,在第一个周期开始时持续性效果发生时,当即就会触发触发器事件,并修改数据模板,延时0.0625秒后执行伤害效果,已经是第二个周期开始时的事了。此时模板已经被修改过了,这样就会应用新的值,但实测结果却是旧值。所以我认为应该是先处理触发器,此时效果还未发生,然后处理效果,而这时触发器已经被处理过了,不会立即响应,所以只有等下个周期再说。但是这样一来就出现一个矛盾,如果先处理触发器,后处理效果,那么伤害效果依旧会在触发器执行之后再执行,为何没有应用新值。所以我觉得数据模板并不是直接起效的,应该是每次周期开始时预先取一次值,这个周期处理行为效果树时时就会使用这个值,即使数据模板被改变了,因为是值引用而不是地址引用,所以预先读取的值并不受影响。而触发器调用的效果却不是这样,而是在调用时另行取值,和行为效果树并不使用同一变量,所以它会立即使用新值。
所以使用触发器来发生效果不存在周期延迟的问题,但是正如你所说,效果树会变成一个独立的,这样虽然在大多数情况下并不受什么影响,但是如果需要读取前边某个效果的目标,则变得非常苦难。
回复

使用道具 举报

 楼主| 发表于 2016-12-21 22:47:25 | 显示全部楼层
本帖最后由 yxxiaobin 于 2016-12-21 22:57 编辑
麦德三世 发表于 2016-12-21 12:10
其实最简单的验证方法:

用触发器直接修改一个伤害效果的模版,然后立即用触发器来执行这个效果。然后看 ...

用触发器来调用效果,让玩家施加给单位会使用新值。
输出时间证实:效果发生后一个周期的时间才会触发效果事件,这样基本上认为:触发器的处理优先度优于效果,所以效果发生时才不会立即触发事件。截图如下:
1.png

用行为来调用效果,预置单位的初始效果居然不能触发事件,所以无法知道探测到它的时间,不过伤害可以确定,是旧值。不过周期效果是能触发事件的,将周期设的极短,并只执行一个周期,这个效果应该发生在0.0625秒,实测在0.125秒被探测到,也符合效果事件会延时一个周期触发的规律。而且因为比设置数据模板晚一个周期,所以使用的是新值。
2.png
如果在初始化时立即创建单位,初始效果能正确触发事件,不过伤害取决于创建单位的时机,如果在修改模板前创建,则使用旧值,否则使用新值。探测到效果时间依旧是在0.0625。另外探测到单位被创建事件也是在0.0625秒,这说明,触发器执行的的动作也不会在当前周期就被触发对应事件,而是要到下一个周期才进行处理。

另外在测试时发现一个很有趣的事情:如果周期设的小于0.0625秒,比如0.01秒,那么也不会在一个周期一下执行好多次,而是把周期视为0.0625秒,每个周期执行一次。但是如果设的大于0.0625秒但不是它的整数倍,却会按照实际值进行计算,当然因为周期因素,会向后取整。这样就会导致有时效果时而隔一个周期执行,时而隔两个周期执行。


回复

使用道具 举报

 楼主| 发表于 2016-12-21 23:05:03 | 显示全部楼层
根据上边的结果也能解释为什么编辑器不提供响应伤害事件直接修改伤害的功能:因为探测到伤害事件时,伤害已经过去一个周期了,我们无法修改历史。
上边有3中情况触发事件,均在一个周期后才发生:效果事件,伤害事件,创建单位事件。可以推测,所有的事件在发生后,都不会立即触发触发器事件,而是延时一个周期。这一规律在某些对事件发生次序和时间需要精确控制的时候非常重要。
另外一个挺意外的事就是:创建单位事件的探测居然晚于效果事件的探测,而不是想象中的创建单位-发生效果-产生伤害这样的顺序。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 23:37 , Processed in 0.137312 second(s), 29 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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