| 08-18-2006, 02:38 PM | #1 |
What condition you should put in order to detect if a unit is facing another unit? I want it to detect so that a certain unit is looking at another unit directly in the face, and it can stray from its facing for up to +30 or -30 degrees, more than that, the condition should return false anyone? thanks. |
| 08-18-2006, 03:07 PM | #2 |
But obviously thats leaking 4 locs per run. |
| 08-18-2006, 03:25 PM | #3 |
I actually use this in AotZ. Mine is a lot simpler than Emjl's. JASS:function IsUnitFacingUnit takes unit source, unit target returns boolean local real sf = GetUnitFacing(source) local real a = AngleBetweenPointsXY(GetUnitX(source), GetUnitY(source), GetUnitX(target), GetUnitY(target)) if sf > a-30 and sf < a+30 then return true endif return false endfunction Here's this function in case you don't use the wc3jass standard one. JASS:function AngleBetweenPointsXY takes real x1, real y1, real x2, real y2 returns real return 57.29582 * Atan2(y2 - y1, x2 - x1) endfunction Mine gives leeway of roughly +/-30 degrees in each direction. That way you don't have to be EXACTLY looking at the target for it to return true. (Since that's nearly impossible to do in game) If you want to adjust that value, just change the '30's in my function to some smaller/greater number. |
| 08-18-2006, 03:25 PM | #4 | |
Quote:
Exactly the same as mine but in Jass :P lol. |
| 08-18-2006, 03:31 PM | #5 |
man that is simpler then mine, heh |
| 08-18-2006, 03:39 PM | #6 |
JASS:local real f1 = GetUnitFacing(yourunit) local real f2 = GetUnitFacing(targetunit) + 180. local real diff = RAbsBJ(f1-f2) local real tolerance = 30. //How far it can be from exact facing return diff <= tolerance or diff >= (360 - tolerance) I think that is what you are looking for. (Note: the other functions posted in the thread will be buggy when, say, one angle is 350 and the other is 10) Edit: Changed it to Absolute. |
| 08-18-2006, 03:41 PM | #7 |
yay, you guys rock. Thanks :D blu da noob's trick did the job. Didnt test the rest since this one seems the shortest way |
| 08-18-2006, 03:42 PM | #8 |
Hmm, wouldn't those only be one unit facing another, but not two facing each other? Edit: blu_da_noob did the right thing, almost. Because if two units were to stand in a parallel line with the accoring facing, it would return true, althought they are not looking into each others face. I think this should work JASS:... local real face1 = GetUnitFacing(unit1) local real face2 = GetUnitFacing(unit2) local location loc1 = GetUnitLoc(unit1) local location loc2 = GetUnitLoc(unit2) local real angle local real temp_face if (face1 > face2) then set temp_face = face1 set face1 = face2 set face2 = temp_face endif set angle = AngleBetweenPoints(loc1,loc2) return ( face1 + angle + 180 == face2 - angle ) ... |
| 08-18-2006, 03:54 PM | #9 |
JASS:function IsUnitFacingUnit takes unit source, unit target returns boolean local real sf = GetUnitFacing(source) local real a = AngleBetweenPointsXY(GetUnitX(source), GetUnitY(source), GetUnitX(target), GetUnitY(target)) local real chk = a - sf local real tol = 30 if (chk >= (-tol) and chk <= tol) or chk >= (360-tol) or chk <= (tol-360) then return true endif return false endfunction Blu's right, as always. This will work. EDIT: Just noticed you already got it, so nvm. :P |
| 08-18-2006, 03:58 PM | #10 |
blu da noobs is the only one that works. Imagine an angle of 1, and the unit facing 359. That will return false while it should be true. Some time ago I wrote some functions JASS:function Angle_Normalize takes real a returns real loop exitwhen a >= 0 set a = a + 360 endloop loop exitwhen a < 360 set a = a - 360 endloop return a endfunction function Angle_Sum takes real a1, real a2 returns real return Angle_Normalize(a1+a2) endfunction function Angle_Diff takes real a1, real a2 returns real return Angle_Normalize(a1-a2) endfunction function Angle_DiffAbsolute takes real a1, real a2 returns real local real r = Angle_Diff(a1,a2) if r > 180 then set r = 360-r endif return r endfunction function Angle_TurnTo takes real a1, real a2 returns real local real r = Angle_Diff(a1,a2) if r > 180.0 then return 1.0 endif return -1.0 endfunction function Angle_WithinRange takes real a1, real a2, real r returns boolean return Angle_DiffAbsolute(a1,a2) < r endfunction They might not be that optimized, but they're quite useful (at least I think so). Angle_WithinRange is the one u're looking for. But then again you already found a solution :) |
| 08-18-2006, 04:29 PM | #11 |
use RMaxBJ(f1,f2) - RMinBJ(f1,f2) because RAbsBJ fucks it up.. |
| 08-18-2006, 05:18 PM | #12 |
... Again, blu_da_noob's function would always work, expect for this case: You need to correct the AngleBetweenPoints from both sides by adding to one and subtrating from the other. (Lol, like my drawings? >>) |
| 08-18-2006, 05:28 PM | #13 |
the second unit's facing has nothing to do with anything. U're missing the point. Either my func or bludanoob or the new one from rising duck should work. Tho I only tested mine ^^ |
| 08-18-2006, 05:32 PM | #14 |
UnMi is correct. You need to check both. JASS:local real f1 = GetUnitFacing(yourunit) local real f2 = GetUnitFacing(targetunit) + 180. local real angle = AngleBetweenUnits(yourunit,targetunit) //Use your equivalent of this local real diff1 = RAbsBJ(f1-f2) local real diff2 = RAbsBJ(f1-angle) local real tolerance = 30. //How far it can be from exact facing return ( diff1 <= tolerance or diff1 >= (360 - tolerance) ) and ( diff2 <= tolerance or diff2 >= (360 - tolerance) ) |
| 08-18-2006, 05:35 PM | #15 | |
Quote:
He wants both units to face each other. |
