Virtual Units
Virtual Units provide a way to dynamically reference units based on roles or other criteria. They automatically resolve to the appropriate unit based on your current group composition and context.
Basic Usage
local tank = Aurora.UnitManager.tank
local healer = Aurora.UnitManager.healer
-- Use virtual units like normal units
if tank.exists then
print("Tank is " .. tank.name)
end
Built-in Virtual Units
Tank
The tank virtual unit resolves in the following order:
- Assigned Main Tank in raid
- Player with Tank role in group
- Player if they are a tank
- Returns
none
unit if no tank is found
local tank = Aurora.UnitManager.tank
-- Examples
if tank.exists then
if tank.hp < 50 then
-- Heal the tank
end
if tank.distanceto(player) < 40 then
-- Stay close to tank
end
end
Healer
The healer virtual unit resolves in the following order:
- Player with Healer role in group
- Player if they are a healer
- Returns
none
unit if no healer is found
local healer = Aurora.UnitManager.healer
if healer.exists and healer.manapct < 20 then
-- Help conserve healer's mana
end
Target
The target property returns a virtual unit representing any unit's current target:
local myTarget = player.target
local tankTarget = tank.target
local healerTarget = healer.target
-- Chain targeting
local targetsTarget = player.target.target -- returns target's target as a unit
This allows you to:
- Access all unit properties on the target
- Chain target references (target of target)
- Handle non-existent targets safely (returns
none
unit if no target)
Example usage:
local unit = Aurora.UnitManager:Get("player")
-- Check if target exists and is an enemy
if unit.target.exists and unit.target.enemy then
-- Do something with the target
end
-- Check target's target
if unit.target.target.exists then
print("My target is targeting " .. unit.target.target.name)
end
-- Check if tank's target matches your target
if tank.target.guid == player.target.guid then
print("We're targeting the same unit!")
end
Custom Virtual Units
You can register your own virtual units:
-- Register a virtual unit for the lowest health party member
Aurora.UnitManager:RegisterVirtualUnit("lowestHealth", function(self)
local lowest = nil
local lowestHP = 100
Aurora.fgroup:each(function(unit)
if unit.alive and unit.hp < lowestHP then
lowest = unit
lowestHP = unit.hp
end
return false
end)
return lowest or self:Get("none")
end)
-- Use it like any other unit
local needsHealing = Aurora.UnitManager.lowestHealth
if needsHealing.exists and needsHealing.hp < 50 then
-- Heal them
end
Best Practices
Usage
- Virtual units are recalculated each time they're accessed
- Use them when you need dynamic unit resolution
- Cache the result if you need to use it multiple times in quick succession
Performance
- Avoid accessing virtual units in tight loops
- Don't create virtual units for static references
- Remember that resolution order matters
Common Use Cases
Tank Swapping
local tank = Aurora.UnitManager.tank
local offtank = Aurora.UnitManager:RegisterVirtualUnit("offtank", function(self)
if IsInRaid() then
for i = 1, GetNumGroupMembers() do
local unit = self:Get("raid" .. i)
if unit.exists and unit.guid ~= tank.guid and
unit.role == "TANK" then
return unit
end
end
end
return self:Get("none")
end)
Emergency Healing
local criticalHealth = Aurora.UnitManager:RegisterVirtualUnit("criticalHealth", function(self)
local critical = nil
local lowestHP = 30 -- Critical threshold
Aurora.fgroup:each(function(unit)
if unit.alive and unit.hp < lowestHP then
critical = unit
lowestHP = unit.hp
end
return false
end)
return critical or self:Get("none")
end)