Skip to content

Character

Utility for getting better types with player characters in roblox

luau
local Players = game:GetService("Players")
local character = require("character")

Players.PlayerAdded:Connect(function(player)
	character.added(player, function(character)
		-- characters always have a primary part, so the character type includes 
		-- Model.PrimaryPart typed as BasePart and not BasePart?
		local rootpart = character.PrimaryPart
		-- doesn't produce a type error like it would with Player.CharacterAdded
		local humanoid = character.Humanoid

		humanoid.Died:Connect(function()
			print("oof")
		end)
	end)
end)

Types

Character

luau
type Character = Model & {
    Humanoid: Humanoid & {
        HumanoidDescription: HumanoidDescription,
        Animator: Animator,
    },
    HumanoidRootPart: BasePart,
    BodyColors: BodyColors,
	PrimaryPart: BasePart,
    Animate: LocalScript,
    Head: BasePart,
}

Methods

added

Wrapper around Player.CharacterAdded, except that if the given Player already has a character it'll run the given callback for the existing character. Unless the third arg dont_run_for_existing_character is true

luau
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local disconnect = character.added(player, function(character)
		character.Humanoid.DisplayName = "🐈"
	end)

	task.wait()
	disconnect()
end)

added_once

Same as added, except that it only runs the callback once and not for every Player.CharacterAdded afterwards.

luau
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	character.added_once(player, function(character)
		character.Humanoid.DisplayName = `{character.Name}'s first character!`
	end)
end)

removing

Wrapper around Player.CharacterRemoving but with the character being typed as the character type instead of just Model

luau
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local disconnect

	disconnect = character.removing(player, function(character)
		print("died")
		disconnect()
	end)
end)

removing_once

Same as removing, except that it only runs the callback once and not for every Player.CharacterRemoving afterwards.

luau
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	character.removing(player, function(character)
		print(`{character.Name}'s first death!`)
	end)
end)

appearance_loaded

Wrapper around Player.CharacterAppearanceLoaded, except that if the given Player already has a character with its appearance loaded it'll run the given callback for the existing character. Unless the third arg dont_run_for_existing_character is true

luau
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local disconnect = character.appearance_loaded(player, function(character)
		character.Humanoid.DisplayName = "🐈"
	end)

	task.wait()
	disconnect()
end)

appearance_loaded_once

Same as appearance_loaded, except that it only runs the callback once and not for every Player.CharacterAppearanceLoaded afterwards.

luau
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local disconnect = character.appearance_loaded_once(player, function(character)
		character.Humanoid.DisplayName = `{character.Name}'s first character with its appearance loaded!`
	end)
end)

get

Wrapper function for Player.Character so you don't have to typecast Player.Character as the Character type

luau
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = character.get(player)

get_appearance_loaded

Same as get except that it'll only return the character, if the player's character has its appearance loaded.

luau
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = character.get_appearance_loaded(player)