找回密码
 点一下
查看: 4741|回复: 10

神奇的SetUnitX/Y

[复制链接]
发表于 2007-1-12 16:43:24 | 显示全部楼层 |阅读模式
不久前老狼发了一篇关于SetUnitX/Y与SetUnitPosition之间效率的对比研究,简述之:SetUnitX/Y要比后者效率高20倍~
嗯,得知后我立即将原来用SetUnitPosition做的东西改成SetUnitX/Y,结果进去一看根本不动了,(原来作了个射箭的技能,箭由单位用timer控制位移),马上debug,首先是做SetUnitX/Y可靠性验证~打字、创造单位、缓存记录、用timer作SetUnitX/Y。。。很好,一切正常。然后回到我的技能,这回干脆些,直接让SetUnitX/Y回归到原点(0,0),测试一看,更纳闷了,箭还是不动。于是考虑可能是其他函数影响所致,于是开始逐行//屏蔽,所用变量尽可能替换为常数,直到~直到
[jass]function ArrowFlyingTime takes nothing returns nothing
local string key="AR"+I2S(h2i(GetExpiredTimer()))
local unit arrow=GetHandleUnitEx(key,"arrow")
call SetUnitX(arrow,GetUnitX(arrow)+30)
call SetUnitY(arrow,GetUnitY(arrow)+40)
//call SetUnitPosition(arrow,GetUnitX(arrow)+dis*Cos(angle),GetUnitY(arrow)+dis*Sin(angle))
endfunction[/jass]
实在不能减下去了,毛病依旧。在整个过程中随时将SetUnitPosition换回来,箭就能以正常轨迹运行。
于是我绝望的想到也许是物体属性的问题。。。(几乎不可能的),于是还原成默认模型。。。小精灵还是不动。。。随后我已经一度认为觉得魔兽灵异的阴影了。。准备放弃,忽然注意到了异象,原来小地图的阴影处被打出了条照亮的通路~于是马上
[jass]call debugmsg("X:"+R2S(GetUnitX(arrow))+" Y:"+R2S(GetUnitY(arrow)))[/jass]
果然得到单位的位置的确在变,但不会被显示出来。。。为什么原来的有显示呢?
居然是因为我将箭的基础移动速度设为0的缘故,在游戏中用SetUnitX就不能让它的图像移动了。。。(实际坐标还是动的)
完整的射箭过程:
[jass]function ArrowStunLast takes nothing returns nothing
local string key="AR"+I2S(h2i(GetExpiredTimer()))
local unit target=GetHandleUnitEx(key,"target")
if GetUnitAbilityLevel(target,'BPSE')>0 then
call UnitRemoveAbility(target,'BPSE')
endif
call FlushStoredMission(LocalVars(),key)
call DestroyGroup(GetHandleGroupEx(key,"filter"))
call DestroyTimer(GetExpiredTimer())
set target=null
endfunction

function ArrowTargetFilter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),Player(GetStoredInteger(LocalVars(),"AR"+I2S(h2i(GetExpiredTimer())),"id")))==true and IsUnitType(GetFilterUnit(),ConvertUnitType(2))==false  and IsUnitType(GetFilterUnit(),ConvertUnitType(25))==false and GetUnitState(GetFilterUnit(),ConvertUnitState(0))>0
endfunction




function ArrowFlyingTime takes nothing returns nothing
local string key="AR"+I2S(h2i(GetExpiredTimer()))
local unit arrow=GetHandleUnitEx(key,"arrow")
local integer lv=GetStoredInteger(LocalVars(),key,"lv")
local integer flytime=GetStoredInteger(LocalVars(),key,"time")
local group g=GetHandleGroupEx(key,"filter")
local real angle=GetStoredReal(LocalVars(),key,"angle")
local real dis=lv*10+20
local location loc=Location(GetUnitX(arrow)+2*dis*Cos(angle),GetUnitY(arrow)+2*dis*Sin(angle))
local real flyheight=GetStoredReal(LocalVars(),key,"flyheight")-GetLocationZ(loc)
local unit stun=null
local unit target=null
call GroupEnumUnitsInRange(g,GetUnitX(arrow),GetUnitY(arrow),dis+20,Condition(function ArrowTargetFilter))
set target=FirstOfGroup(g)

if target != null then
if IsUnitType(target,ConvertUnitType(26)) then
call UnitDamageTarget(arrow,target,120*lv,true,true,ConvertAttackType(0),ConvertDamageType(5),ConvertWeaponType(0))
call KillUnit(arrow)
call FlushStoredMission(LocalVars(),key)
call DestroyTimer(GetExpiredTimer())
call DestroyGroup(g)        
else

set stun=CreateUnit(GetOwningPlayer(arrow),'e00G',GetUnitX(arrow),GetUnitY(arrow),angle*bj_RADTODEG)
call UnitAddAbility(stun,'A04Z')
call UnitApplyTimedLife(stun,'B000',0.3)
if IssueTargetOrder(stun,"thunderbolt",target) then
call UnitDamageTarget(arrow,target,120*lv,true,true,ConvertAttackType(0),ConvertDamageType(5),ConvertWeaponType(0))
if GetUnitState(target,ConvertUnitState(0))>0 then
call StoreInteger(LocalVars(),key,"target",h2i(target))
if IsUnitType(target,ConvertUnitType(0))==true then
set dis=2
else
set dis=1
endif
call TimerStart(GetExpiredTimer(),(lv*10+20)*flytime/(dis*250),false,function ArrowStunLast)
else
call FlushStoredMission(LocalVars(),key)
call DestroyTimer(GetExpiredTimer())
call DestroyGroup(g)
endif
call KillUnit(arrow)
else
call UnitDamageTarget(arrow,target,60*lv,true,true,ConvertAttackType(0),ConvertDamageType(5),ConvertWeaponType(0))
endif
endif
elseif flytime > 33+lv or flyheight<0  then
call PauseTimer(GetExpiredTimer())

call FlushStoredMission(LocalVars(),key)
call DestroyTimer(GetExpiredTimer())
call DestroyGroup(g)
call KillUnit(arrow)
endif
call SetUnitX(arrow,GetUnitX(arrow)+dis*Cos(angle))
call SetUnitY(arrow,GetUnitY(arrow)+dis*Sin(angle))
call debugmsg("X:"+R2S(GetUnitX(arrow))+" Y:"+R2S(GetUnitY(arrow)))
//call SetUnitPosition(arrow,GetUnitX(arrow)+dis*Cos(angle),GetUnitY(arrow)+dis*Sin(angle))
call SetUnitFlyHeight(arrow,flyheight,0)
call StoreInteger(LocalVars(),key,"time",flytime+1)
call GroupClear(g)
call RemoveLocation(loc)
set arrow=null
set g=null
set target =null
set loc=null
endfunction

function ArrowSetoff takes nothing returns nothing
local location loc=GetSpellTargetLoc()
local real angle=Atan2(GetLocationY(loc) - GetUnitY(GetTriggerUnit()), GetLocationX(loc) - GetUnitX(GetTriggerUnit()))
local unit arrow=CreateUnit(GetTriggerPlayer(),'e00L',GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),angle*bj_RADTODEG)
local timer t=CreateTimer()
local string key="AR"+I2S(h2i(t))
local group g=CreateGroup()
local integer lv=GetUnitAbilityLevel(GetTriggerUnit(),GetSpellAbilityId())
call UnitApplyTimedLife(arrow,'B000',2)
call StoreReal(LocalVars(),key,"angle",angle)
call StoreInteger(LocalVars(),key,"arrow",h2i(arrow))
call StoreInteger(LocalVars(),key,"filter",h2i(g))
call StoreInteger(LocalVars(),key,"lv",lv)
call StoreInteger(LocalVars(),key,"id",GetPlayerId(GetTriggerPlayer()))
call FlushStoredInteger(LocalVars(),key,"time")

call TimerStart(t,0.04,true,function ArrowFlyingTime)

call RemoveLocation(loc)
set loc=GetUnitLoc(arrow)
call StoreReal(LocalVars(),key,"flyheight",GetLocationZ(loc)+100)
call RemoveLocation(loc)
set loc=null
set t=null
set g=null
set arrow=null
endfunction[/jass]

评分

参与人数 1威望 +2 收起 理由
麦德三世 + 2

查看全部评分

 楼主| 发表于 2007-1-12 17:08:14 | 显示全部楼层
SetUnitX/Y效率和反应果然远远强于SetUnitPosition,现在对高度的修正选取点的距离都要减半了。
回复

使用道具 举报

 楼主| 发表于 2007-1-12 17:15:38 | 显示全部楼层
反思:像单位的基础移动,作为辅助单位一般都让它为零或负让其无法移动,其实影响还是挺大的,出了去除'Amov',一些官方技能也会无效化,具体的如闪烁、嘲讽。但没想到甚至可能影响到某些函数的效果。。。
回复

使用道具 举报

发表于 2007-1-12 19:01:52 | 显示全部楼层
可以用触发将单位速度设为0而不是通过物体编辑器~~这样就没有上面所说的这些问题~~

不过~~别忘记把游戏平衡常数中的单位最低移动速度也设为0

不过~~依然值得加分~~
回复

使用道具 举报

发表于 2007-1-12 19:06:27 | 显示全部楼层
加个减速100%的技能也不会这样
回复

使用道具 举报

发表于 2007-1-12 19:54:50 | 显示全部楼层
e...

我怎么喜欢把辅助单位速度设为522呢。。。
回复

使用道具 举报

发表于 2007-1-12 19:56:28 | 显示全部楼层
把可以逃跑选项去掉它就不会乱动了
回复

使用道具 举报

发表于 2009-1-2 22:10:47 | 显示全部楼层
其实我也发现过这个问题。
回复

使用道具 举报

发表于 2009-1-3 21:45:45 | 显示全部楼层
发现过类似问题
移动速度设成1就可以了
回复

使用道具 举报

发表于 2012-2-6 13:40:54 | 显示全部楼层
没想到5年前的贴解决了我困惑几天的问题,谢谢你了
回复

使用道具 举报

发表于 2012-2-6 21:51:30 | 显示全部楼层
噗...这坟挖的...
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 11:06 , Processed in 0.068681 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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