Created
February 6, 2022 07:05
-
-
Save eldonwilliams/c49b2804a361f32187bed48a191aa83b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local Players = game:GetService("Players") | |
local R15Blank = game:GetService("ReplicatedStorage"):WaitForChild("Assets"):WaitForChild("R15Blank") | |
local LoadCharacter = {} | |
-- Generally useful types | |
export type BrickColorID = number | |
export type AssetType = string | |
export type CharacterAsset = { | |
id: number, | |
assetType: { | |
name: AssetType, | |
id: number, | |
}, | |
name: string, | |
} | |
export type CharacterAppearance = { | |
playerAvatarType: Enum.GameAvatarType, | |
defaultPantsApplied: boolean, | |
defaultShirtApplied: boolean, | |
scales: { | |
bodyType: number, | |
head: number, | |
height: number, | |
proportion: number, | |
depth: number, | |
width: number, | |
}, | |
bodyColors: { | |
leftArmColorId: BrickColorID, | |
torsoColorId: BrickColorID, | |
rightArmColorId: BrickColorID, | |
headColorId: BrickColorID, | |
leftLegColorId: BrickColorID, | |
rightLeftColorId: BrickColorID, | |
}, | |
assets: Array<CharacterAsset>, | |
} | |
-- Internal types | |
export type HumanoidDescriptionModifier = (description: HumanoidDescription) -> HumanoidDescription | |
local function doesPropertyExist(object: Instance, property: string) | |
local exists,_ = pcall(function() | |
assert(object[property], "oof") | |
end) | |
return exists | |
end | |
--[=[ | |
Generates a character model from a HumanoidDescription object. | |
@param description HumanoidDescription -- | |
@return Model | |
]=] | |
function LoadCharacter.fromHumanoidDescription(description: HumanoidDescription): Model | |
local cloneBlank = R15Blank:Clone() | |
if (not cloneBlank:IsDescendantOf(workspace)) then | |
cloneBlank.Parent = workspace | |
end | |
cloneBlank:FindFirstChild("Humanoid"):ApplyDescription(description) | |
return cloneBlank | |
end | |
--[=[ | |
Generates a character model from a userId. The userId must exist within the game and whatever cavets Players:GetCharacterAppearanceInfoAsync() has. | |
Also note this function is more-or-less a binding around LoadCharacter.fromHumanoidDescription(), that may suit your needs | |
@param userId number -- This is the userId you wish to use | |
@param modifier HumanoidDescriptionModifier -- A function which can modify the humanoid description | |
@return Model | |
]=] | |
function LoadCharacter.fromUserId(userId: number, modifier: HumanoidDescriptionModifier): Model | |
local characterData: CharacterAppearance = Players:GetCharacterAppearanceInfoAsync(userId) | |
local description = Instance.new("HumanoidDescription") | |
for colorName, value in pairs(characterData.bodyColors) do | |
local colorProperty: string, _ = colorName:sub(1,-3):gsub("^%l", string.upper) | |
if (doesPropertyExist(description, colorProperty)) then | |
description[colorProperty] = BrickColor.new(value).Color | |
else | |
warn(colorProperty, "did not exist!") | |
end | |
end | |
for scaleName, value in pairs(characterData.scales) do | |
local scaleProperty: string, _ = (scaleName .. "Scale"):gsub("^%l", string.upper) | |
if (doesPropertyExist(description, scaleProperty)) then | |
description[scaleProperty] = value | |
else | |
warn(scaleProperty, "did not exist!") | |
end | |
end | |
for _, assetData in ipairs(characterData.assets) do | |
local assetTypeSpaceless: string, _ = assetData.assetType.name:gsub("%s+", "") | |
if (doesPropertyExist(description, assetTypeSpaceless)) then | |
if (assetTypeSpaceless:find("Accessory")) then | |
description[assetTypeSpaceless] = description[assetTypeSpaceless] .. "," .. assetData.id | |
continue | |
end | |
description[assetTypeSpaceless] = assetData.id | |
continue | |
end | |
if (doesPropertyExist(description, assetTypeSpaceless .. "Accessory")) then | |
description[assetTypeSpaceless .. "Accessory"] = description[assetTypeSpaceless .. "Accessory"] .. "," .. assetData.id | |
continue | |
end | |
warn(assetData.assetType.name, "did not exist!") | |
end | |
if (modifier and type(modifier) == "function") then | |
description = modifier(description) | |
end | |
return LoadCharacter.fromHumanoidDescription(description) | |
end | |
--[=[ | |
Generates a character model from a Player object. | |
Also note this function is more-or-less a binding around LoadCharacter.fromHumanoidDescription() and LoadCharacter.fromUserId, which either may suit your needs | |
@param userId number -- This is the userId you wish to use | |
@param modifier HumanoidDescriptionModifier -- A function which can modify the humanoid description | |
@return Model | |
]=] | |
function LoadCharacter.fromPlayer(player: Player, modifier: HumanoidDescriptionModifier) | |
return LoadCharacter.fromUserId(player.UserId, modifier) | |
end | |
return LoadCharacter |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment