找回密码
 点一下
查看: 3003|回复: 3

【研究】对SetUnitPosition和SetX,SetY的说明

[复制链接]
发表于 2009-1-7 22:39:05 | 显示全部楼层 |阅读模式
【研究】对SetUnitPosition和SetX,SetY的说明
老狼当初说SetUnitPosition相对SetUnitX,SetUnitY效率低下,今天打算把以前写的SetSetUnitPosition替换掉。
但忽然发现以前写的冲锋出了神奇的BUG。

[codes=jass]
function Assault takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit ua =GetHandleUnit(t,"Assault_ua")
    local integer i = GetHandleInt(t,"Assault_i")
    local real ang = GetUnitFacing(ua)
    local real UnitLocX = GetUnitX(ua)
    local real UnitLocY = GetUnitY(ua)
    local real teplocX
    local real teplocY
    local effect e
    set i = i + 1
    call SetHandleInt(t,"Assault_i",i)
    if (i < 30 ) and (IsUnitAliveBJ(ua)==true)then
    set teplocX = UnitLocX+ 2 * i*Cos(ang*bj_DEGTORAD)
    set teplocY = UnitLocY+ 2 * i*Sin(ang*bj_DEGTORAD)
        if ( MoveAble(teplocX,teplocY,55) == true ) then
        call SetUnitXY(ua,teplocX,teplocY)//一个函数,相当于SetFacing,SetX,SetY
        call SetUnitAnimationByIndex( ua, 2 )
        set e = AddSpecialEffect("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", teplocX, teplocY)
        call DestroyEffect( e )
        set e = null
        endif
    else
    call EndTimer(t)
    call SetUnitAnimationByIndex(ua,7)
    call SetUnitPathing( ua, true )
    call UnitRemoveAbility( ua, 'A01P' )
    endif
endfunction

function Assault_Actions takes unit ua returns nothing
    local timer t = CreateTimer()
    local integer lv = GetUnitAbilityLevel(ua, 'A01G')
    call SetUnitAnimationByIndex( ua, 2 )
    call SetUnitPathing( ua, false )
    call UnitAddAbility( ua, 'A01P' )
    call SetUnitAbilityLevel( ua, 'A01P', lv )
    call SetHandleHandle(t,"Assault_ua",ua)
    call SetHandleInt(t,"Assault_i",1)
    call TimerStart(t,0.05,true,function Assault)
    set ua = null
    set t = null
endfunction

[/codes]

然后发现神奇的结果是单位会在冲锋的过程中转动身体,于是我增加了角度判定,但单位会在接受命令时迅速被打断动作,视觉效果非常差。


个人猜测SetUnitPosition对单位发布命令有一定延迟作用,从而快速移动导致的问题。
这个命令就是SetUnitPosition拥有的打断技能的效果。

从以上可以看出,
只要是单纯的模拟效果类技能(比如模拟球体围绕单位旋转),这样不需要单位释放命令的技能都可以使用效率较高的SetUnitX,SetUnitY
如果是冲锋类没有禁止玩家控制的话,那么最好使用SetUnitPosition视觉效果比较好。


应该不是什么新鲜东西,不过似乎没人写下来过,给不知道的人看看。

评分

参与人数 1威望 +33 收起 理由
kook + 33 欢迎讨论

查看全部评分

发表于 2009-1-7 23:28:15 | 显示全部楼层
好像好多人研究这个 个人感觉 SetUnitX() SetUnitY() 他就是2个函数 他要做两次事情
SetUnitPosition()是一个函数 他就是做一个事情 当然SetUnitPosition函数效率低一些 但是从暴雪自己的给触发器的调用的函数 都是调用SetUnitPosition 当然有他的目的性
我记得某人发帖过用  SetUnitX() SetUnitY()  移动单位到区域 触发了2次区域事件 暴雪估计就是为了处理这个类似的问题才弄出了 SetUnitPosition() 为了解决问题当然就多了好多逻辑处理 效率自然也就慢了
不过效率慢了20倍 我怎不知道老狼怎么算出来的. 难道他反汇编看过 还是拿个性能测试工具在那测试出来的
至于LZ说转身被打断了 额 我记得暴雪的触发是先移动位置再设置面向角度 这个应该有一点关系 我是这样觉得的 而且转身还跟转身速度 移动速度有关 我记得我以前弄过一个甩链球的技能 我的人才转了3圈 那个链球转了4+圈
话说SetUnitX() SetUnitY()  移动单位不打断动作? 我还真没怎么使用过这两个函数
回复

使用道具 举报

发表于 2009-1-7 23:37:38 | 显示全部楼层
在我的印象里,SetUnitX,SetUnitY是不会打断单位的当前命令,同时由于不检查地形限制,所以有更高的运行效率。所以球体旋转,黑洞吸引单位的效果,都应当使用它们来处理。

在需要侦测地图移动类型时,时刻添加判断
[codes=jass]
这个可以使单位不能冲过断崖。
boolean B=(not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY))
嗯,这个可以过断崖,但是不会冲出地图的黑色部分。
boolean B=(not IsTerrainPathable(x,y,PATHING_TYPE_FLYABILITY))
使用以上的办法可以不再需要判断x于maxX,minX的大小。也算是比较简单吧。[/codes]

另外,在单位默认的移动速度为0时,SetUnitX,SetUnitY可以改变单位的X,Y坐标的值,但是单位没有移动的视觉效果。听说在触发中再设置单位的移动速度为0可以避免这个Bug,但我没有经过实测,所以不确定。

由于它们不会打断单位的当前命令,所以会出现冲锋过程中攻击敌方的问题。如果Lz不想设置冲锋的单位暂停的话,我觉得可以用锤子来砸下单位,这样既可以使得单位有一个冲锋的Buff,又不会攻击或者做别的动作了。SetUnitPosition函数的话,即使不暂停他,他也不会做出很多的动作吧。
回复

使用道具 举报

发表于 2009-1-8 00:19:47 | 显示全部楼层
SetUnitPosition相当于每次移动都会发布一个停止命令,所以移动频率快的话单位做不了事
SetUnitX,SetUnitY可以和通魔很完美的配合

另外单位移动速度为0即没有移动能力的话,SetUnitX,SetUnitY会把单位实际移过去但表面还在原地。。。用触发设置单位移动速度为0,其实并不为0而是1,单位还具有移动能力,而移除单位的Amov技能能够让单位丧失移动能力但SetUnitX,SetUnitY能正确移动该单位
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-21 22:21 , Processed in 0.083297 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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