HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Detect unit facing unit?

08-18-2006, 02:38 PM#1
vile
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
The)TideHunter(
Trigger:
And - All (Conditions) are true
Collapse Conditions
(Facing of SomeUnit) Less than or equal to ((Angle from (Position of SomeUnit) to (Position of SomeOtherUnit)) + 30.00)
(Facing of SomeUnit) Greater than or equal to ((Angle from (Position of SomeUnit) to (Position of SomeOtherUnit)) - 30.00)
But obviously thats leaking 4 locs per run.
08-18-2006, 03:25 PM#3
Rising_Dusk
I actually use this in AotZ.
Mine is a lot simpler than Emjl's.

Collapse 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.
Collapse 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
The)TideHunter(
Quote:
Originally Posted by Rising_Dusk
I actually use this in AotZ.
Mine is a lot simpler than Emjl's.

Collapse 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

Exactly the same as mine but in Jass :P
lol.
08-18-2006, 03:31 PM#5
emjlr3
man that is simpler then mine, heh
08-18-2006, 03:39 PM#6
blu_da_noob
Collapse 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
vile
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
UnMi
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
Collapse 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
Rising_Dusk
Collapse 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
iNfraNe
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

Collapse 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
vile
use RMaxBJ(f1,f2) - RMinBJ(f1,f2) because RAbsBJ fucks it up..
08-18-2006, 05:18 PM#12
UnMi
...
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? >>)
Attached Images
File type: jpgface.JPG (13.1 KB)
08-18-2006, 05:28 PM#13
iNfraNe
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
blu_da_noob
UnMi is correct. You need to check both.

Collapse 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
UnMi
Quote:
Originally Posted by iNfraNe
the second unit's facing has nothing to do with anything. U're missing the point.
I would read vile's post again.
He wants both units to face each other.