| 04-12-2009, 12:28 AM | #1 |
Hello, I have some troubles with rects and the enter rect event. Sometimes when a unit moves from one rect to another the game gets a "EnterRect" event but the unit is still in the rect it came from according to RectContainsUnit(). Is there an easy and reliable way to avoid this problem? I attached a test map to describe the problem better. It seems to only happen when you move to the Region 001 which is a bit weird to me. Thanks in advance. |
| 04-12-2009, 08:45 AM | #2 |
If the unit enter in a rect from the right, GetUnitX > xMax of rect. If the unit enter in a rect from the top, GetUnitY > yMax of rect. It's a bug, that's all. So in your case, considering your rects are near each other without any space beetween them, it will fail for the 2 examples. (green and light blue ) The easiest way is to use a short wait, a Timer(0) should do the job, but i'm not sure, if you don't use jass then simply use a PolledWait(0), but the wait will be about 0.2 s |
| 04-12-2009, 08:58 AM | #3 | |
Quote:
Thanks for the reply. The problem with a sleep is that it might not work, if you move your unit to the exact border of the area and then don't move for the sleep time you will go in undetected. I think I fixed the problem. Since I just wanted to detect the units going in the simplest solution was to rewrite the functionality in more triggers instead of one. Instead of having to use RectContainsUnit() I know which rect the unit entered because it is the only one registered to the trigger. |
| 04-12-2009, 09:02 AM | #4 |
The problem with a sleep is that it might not work, if you move your unit to the exact border of the area and then don't move for the sleep time you will go in undetected. I bet you can't do that. But sure one trigger and one event will work, you simply asked for an easy way. |
| 04-12-2009, 09:10 AM | #5 | ||
Quote:
Quote:
The space between them doesn't matter, right? |
| 04-12-2009, 09:20 AM | #6 | |
Quote:
The space does matter for the function RectContainsUnit, if the rects are near each other without any space, then in cases i said the unit will be considered in the last leaving rect. (in theory, i can't test it now) If there is a space, the unit will be consider out of all rects, that's what i wanted to say. |
| 04-12-2009, 03:27 PM | #7 |
Some clarification: rects and regions are different, how different? Very different. Rect: A group of 4 values describing minx,maxx,miny and maxy. Region: A set of points that can fire enter/leave events. When you register a rect region event, it actually creates a region, add the points in the rect to the region and registers the event for the region. Even more is that region events fire when the unit's collision circle enters the region. But IsUnitInRectBJ (or whatever that function is called) checks whether the unit's origin (the center of the collision circle) is in the rect. Don't worry, this is solvable. Just need a way to check if a unit's colllision is in range of a point (and we got IsUnitInRangeOfXY) then use some equations, I think I'll post a function soon. Edit: IsUnitAtRect |
| 04-12-2009, 03:47 PM | #8 |
I know the difference and i think Slin as well, "Region" is just the default word when you create a rect on the map. Maybe you're right with the collision, but why it fails only with right and top ? |
| 04-13-2009, 03:48 AM | #9 |
I'm pretty sure this isn't an issue with collision sizes, else it wouldn't work no matter what direction you enter the rect/region from, but I remember from my tests as well that if you would enter a rect from the south side for example the unit would be inside the rect on the "unit enters region" event. |
| 04-13-2009, 07:26 AM | #10 |
I can't test now but i'm pretty sure as well. Can someone to use a Timer(0) when the event enter region fire, on each side of the rect ? |
| 04-13-2009, 01:09 PM | #11 |
Try this function: JASS:native IsUnitInRegion takes region whichRegion, unit whichUnit returns boolean |
| 04-13-2009, 01:37 PM | #12 |
Why don´t use GetTriggeringRegion()? |
| 04-13-2009, 03:05 PM | #13 |
Depends what he want, sure he could link the rect with the region but there are many functions with rect, few with region. Actually i just want to know if it as an bug which can fixed with a timer(0) or if it as Vexorian said, but again so why the unit is considered in the region when she come from bottom and left ?! I don't have war3 at the moment, so i can't test it myself. But eventually i can make the test code if someone want to test it but dunno why (or too lazy) |
| 04-13-2009, 06:02 PM | #14 |
Could someone test this script : JASS:library TestRect initializer init globals // A region care about numbers multiple of 32 (size of a cell) when you add it a rect private real Xmin = 0. private real Ymin = 0. private real Xmax = 320. private real Ymax = 320. private constant real TIME_OUT = 0. endglobals globals private region Reg private rect Rec private unit U private timer Tim endglobals private function Test takes nothing returns nothing call BJDebugMsg(" ") call BJDebugMsg("AFTER A " + R2S(TIME_OUT) + " TIMER") call BJDebugMsg("GetUnitX == " + R2S(GetUnitX(U))) call BJDebugMsg("GetUnitY == " + R2S(GetUnitY(U))) if RectContainsUnit(Rec,U) then call BJDebugMsg("the unit is inside the rect") else call BJDebugMsg("the unit is outside the rect") endif if IsUnitInRegion(Reg,U) then call BJDebugMsg("the unit is inside the region") else call BJDebugMsg("the unit is outside the region") endif endfunction private function Actions takes nothing returns nothing call BJDebugMsg(" ") call BJDebugMsg("GetUnitX == " + R2S(GetUnitX(U))) call BJDebugMsg("GetUnitY == " + R2S(GetUnitY(U))) if RectContainsUnit(Rec,U) then call BJDebugMsg("the unit is inside the rect") else call BJDebugMsg("the unit is outside the rect") endif if IsUnitInRegion(Reg,U) then call BJDebugMsg("the unit is inside the region") else call BJDebugMsg("the unit is outside the region") endif call TimerStart(Tim,TIME_OUT,false,function Test) endfunction private function init takes nothing returns nothing local trigger trig = CreateTrigger() set Tim = CreateTimer() set U = CreateUnit(Player(0),'hpea',Xmin-300.,Ymin-300.,0.) set Reg = CreateRegion() set Rec = Rect(Xmin,Ymin,Xmax,Ymax) call RegionAddRect(Reg,Rec) call PauseUnit(CreateUnit(Player(12),'hfoo',Xmin,Ymin,0.),true) call PauseUnit(CreateUnit(Player(12),'hfoo',Xmin,Ymax,0.),true) call PauseUnit(CreateUnit(Player(12),'hfoo',Xmax,Ymin,0.),true) call PauseUnit(CreateUnit(Player(12),'hfoo',Xmax,Ymax,0.),true) call TriggerRegisterEnterRegion(trig,Reg,null) call TriggerAddAction(trig,function Actions) endfunction endlibrary Maybe there are errors, i didn't compile it. Also i realize that even if it works there is no GetTriggeringRect(), so anyway we would need to attach the region to the rect. And ofc in a real map we would need attach datas to the timer. |
| 04-24-2009, 05:33 PM | #15 |
Tested and IsUnitRegion works fine with this event. But i still consider it as a bug for the rect, because it works well when an unit come to the bottom or the left of the rect, and not when the unit come to the up or the right. |
