Custom enum for working with direction

While working on Blox, I wrote a module that functioned essentially as a beefed-up NormalId enum. It has more intuitive constants and plenty of useful properties for you to use, as well as methods of converting to and from other data types.

The code is below, feel free to use it in your own projects :slightly_smiling_face:

--[[
	
	Facing
	a better enum for working with faces
	
	by Elttob
	
--]]

local Facing = {}
Facing.__index = Facing

local normalIDOpposites = {
	[Enum.NormalId.Top] = Enum.NormalId.Bottom,
	[Enum.NormalId.Bottom] = Enum.NormalId.Top,
	[Enum.NormalId.Front] = Enum.NormalId.Back,
	[Enum.NormalId.Back] = Enum.NormalId.Front,
	[Enum.NormalId.Left] = Enum.NormalId.Right,
	[Enum.NormalId.Right] = Enum.NormalId.Left
}

local normalIDToFacingMap = {}
local facingIDToFacingMap = {}

Facing.allFacings = {}

local function newFacing(normalID, facingID)
	local obj = setmetatable({}, Facing)
	obj.normalID = normalID
	obj.facingID = facingID
	normalIDToFacingMap[normalID] = obj
	facingIDToFacingMap[facingID] = obj
	Facing.allFacings[#Facing.allFacings + 1] = obj
	return obj
end

function Facing.fromNormalID(normalID)
	return normalIDToFacingMap[normalID]
end

function Facing.fromFacingID(facingID)
	return facingIDToFacingMap[facingID]
end

Facing.TOP = newFacing(Enum.NormalId.Top, 1)
Facing.BOTTOM = newFacing(Enum.NormalId.Bottom, 2)
Facing.FRONT = newFacing(Enum.NormalId.Front, 4)
Facing.BACK = newFacing(Enum.NormalId.Back, 8)
Facing.LEFT = newFacing(Enum.NormalId.Left, 16)
Facing.RIGHT = newFacing(Enum.NormalId.Right, 32)

Facing.UP = Facing.TOP
Facing.DOWN = Facing.BOTTOM

Facing.X_POSITIVE = Facing.RIGHT
Facing.X_NEGATIVE = Facing.LEFT
Facing.Y_POSITIVE = Facing.UP
Facing.Y_NEGATIVE = Facing.DOWN
Facing.Z_POSITIVE = Facing.BACK
Facing.Z_NEGATIVE = Facing.FRONT

for _, facing in pairs(normalIDToFacingMap) do
	facing.direction = Vector3.FromNormalId(facing.normalID)
	facing.opposite = Facing.fromNormalID(normalIDOpposites[facing.normalID])
	facing.axis = Vector3.new(
		facing.direction.X ~= 0 and 1 or 0,
		facing.direction.Y ~= 0 and 1 or 0,
		facing.direction.Z ~= 0 and 1 or 0
	)
end

return Facing

Module API


Facing.TOP

The Facing object for the positive Y direction.

Aliases: UP, Y_POSITIVE


Facing.BOTTOM

The Facing object for the negative Y direction.

Aliases: DOWN, Y_NEGATIVE


Facing.FRONT

The Facing object for the negative Z direction.

Aliases: Z_NEGATIVE


Facing.BACK

The Facing object for the positive Z direction.

Aliases: Z_POSITIVE


Facing.LEFT

The Facing object for the negative X direction.

Aliases: X_NEGATIVE


Facing.RIGHT

The Facing object for the positive Xdirection.

Aliases: X_POSITIVE


Facing.allFacings

Stores references to all 6 Facing objects (up, down, left, right, front, back) as a list.
The order of the list is undefined, and shouldn’t be relied upon.


Facing.fromNormalID(Enum.NormalId normalID)

Returns the Facing object for the given NormalId.


Facing.fromFacingID(int facingID)

Returns the Facing object for the given integer ID, corresponding to the facingID property of the Facing object.


Facing object API


Facing.normalID

Stores the NormalId enum for this Facing object.


Facing.facingID

Stores an integer ID for this Facing object, useful for combining and serialising Facing objects.


Facing.direction

Stores a Vector3 direction for this Facing object (normal to the face represented by this object)


Facing.opposite

Stores the Facing object pointing in the opposite direction of this Facing object.


Facing.axis

Stores a Vector3 representing the axis this Facing object is oriented along.
For example, Facing.X_POSITIVE and Facing.X_NEGATIVE have axis values of (1, 0, 0)


25 Likes

Does this enum support knowing which side a item is touched from (If a player is touched from the top of its HumanoidRootPart)?

2 Likes

That’s outside the scope of the module - it’s only meant to act as an enum - but you could definitely implement it yourself using this module :slightly_smiling_face:

2 Likes