This may look a bit like overkill but here is what I'm using (the coordinate stuff is a modification of
code provided by elcius):
Code:
local GetBestMapForUnit, UnitPosition = C_Map.GetBestMapForUnit, UnitPosition
local GetWorldPosFromMapPos = C_Map.GetWorldPosFromMapPos
local mapID, offsetX, offsetY, scaleX, scaleY, vector = nil, { }, { }, { }, { }, CreateVector2D(0, 0)
local mt = { __index = function(self, mapID)
vector.x, vector.y = 0, 0
local _, offset = GetWorldPosFromMapPos(mapID, vector)
vector.x, vector.y = 1, 1
local _, scale = GetWorldPosFromMapPos(mapID, vector)
offsetX[mapID], offsetY[mapID] = offset.x, offset.y
scaleX[mapID], scaleY[mapID] = scale.x - offset.x, scale.y - offset.y
return self[mapID]
end }
setmetatable(offsetX, mt)
setmetatable(offsetY, mt)
setmetatable(scaleX, mt)
setmetatable(scaleY, mt)
local frame = CreateFrame("Frame", nil, UIParent)
local timer, X, Y = 1
frame:SetScript("OnUpdate", function(self, elapsed)
timer = timer + elapsed
if timer < 0.1 then return end
timer = 0
local x, y = UnitPosition("player")
if x and y then -- Reversed axis
x, y = (y - offsetY[mapID]) / scaleY[mapID], (x - offsetX[mapID]) / scaleX[mapID]
if x ~= X or y ~= Y then
-- Update coordinates stuff here
X, Y = x, y
end
end
end)
frame:SetScript("OnEvent", function(self, event)
mapID = GetBestMapForUnit("player")
if mapID and UnitPosition("player") then
self:Show()
else
self:Hide()
timer, X, Y = 1, nil, nil
end
end)
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("NEW_WMO_CHUNK")
frame:RegisterEvent("ZONE_CHANGED")
frame:RegisterEvent("ZONE_CHANGED_NEW_AREA")