Skip to content

Instantly share code, notes, and snippets.

@RuizuKun-Dev
Forked from EgoMoose/RthroScaleFix.lua
Created March 16, 2021 22:33
Show Gist options
  • Save RuizuKun-Dev/c1ae8b10a1be40c8c879f21b2e85fb3a to your computer and use it in GitHub Desktop.
Save RuizuKun-Dev/c1ae8b10a1be40c8c879f21b2e85fb3a to your computer and use it in GitHub Desktop.
Adjusts Roblox Rthro avatars so that their height scales match a 5 stud high R15 rig
local CLASSIC_HEIGHT = 5
local function getObjectValue(parent: Instance, name: string, default)
local found = parent:FindFirstChild(name)
if found then
return found.Value
end
return default
end
local function matchHeadToMesh(head, headMesh)
for _, child: Instance in pairs(head:GetChildren()) do
if child:IsA("Attachment") and not headMesh:FindFirstChild(child.Name) then
local Attacthment: Attacthment = child
local vec3Copy = Instance.new("Vector3Value")
vec3Copy.Name = Attacthment.Name
vec3Copy.Value = Attacthment.Position
vec3Copy.Parent = headMesh
end
end
local partScaleType = head:FindFirstChild("AvatarPartScaleType")
if partScaleType and not headMesh:FindFirstChild("AvatarPartScaleType") then
partScaleType:Clone().Parent = headMesh
end
end
local function getMaxHeight(humanoid: Humanoid)
local humanoidRootPart = humanoid.RootPart
local character = humanoid.Parent
local upperTorso = character.UpperTorso
local head = character.Head
local root = character.LowerTorso.Root
local waist = upperTorso.Waist
local neck = head.Neck
-- part0 * c0 == part1 * c1
local lowerTorsoCF = root.C0 * root.C1:Inverse()
local upperTorsoCF = lowerTorsoCF * waist.C0 * waist.C1:Inverse()
local headCF = upperTorsoCF * neck.C0 * neck.C1:Inverse()
local upperTorsoTop = upperTorsoCF.Y + upperTorso.Size.Y / 2
local headTop = headCF.Y + head.Size.Y / 2
-- Sometimes the upper torso is higher than the head.
-- For example: https://www.roblox.com/bundles/429/Magma-Fiend
return math.max(upperTorsoTop, headTop) + humanoidRootPart.Size.Y / 2 + humanoid.HipHeight
end
local function rthroScaleFix(character: Model)
local humanoid = character.Humanoid
local humanoidRootPart = humanoid.RootPart
local floorCF = humanoidRootPart.CFrame * CFrame.new(0, -(humanoidRootPart.Size.Y / 2 + humanoid.HipHeight), 0)
local height = getMaxHeight(humanoid)
local scale = (CLASSIC_HEIGHT / height) * getObjectValue(humanoid, "BodyHeightScale", 1)
local head = character.Head
local headMesh = head:FindFirstChildWhichIsA("SpecialMesh")
local isFileMesh = (headMesh.MeshType == Enum.MeshType.FileMesh)
local accessories = {}
for _, child: Instance in pairs(character:GetChildren()) do
if child:IsA("Accessory") then
local Accessory: Accessory = child
local handle = Accessory:FindFirstChildWhichIsA("BasePart")
local weld = handle:FindFirstChild("AccessoryWeld")
weld:Destroy()
Accessory.Parent = nil
accessories[Accessory] = true
end
end
matchHeadToMesh(head, headMesh)
for _, child: Instance in pairs(character:GetDescendants()) do
if child:IsA("Motor6D") then
local Motor6D: Motor6D= child
local p0 = Motor6D.C0.Position
local p1 = Motor6D.C1.Position
Motor6D.C0 = (Motor6D.C0 - p0) + p0 * scale
Motor6D.C1 = (Motor6D.C1 - p1) + p1 * scale
elseif child:IsA("Attachment") then
local Attachment: Attachment = child
Attachment.Position = Attachment.Position * scale
Attachment.OriginalPosition.Value = Attachment.OriginalPosition.Value * scale
elseif child.Name == "OriginalSize" then
local parent = child.Parent
if parent:IsA("BasePart") then
parent.Size = parent.Size * scale
child.Value = child.Value * scale
elseif parent == headMesh then
for _, v3 in pairs(parent:GetChildren()) do
if v3:IsA("Vector3Value") and v3 ~= child then
v3.Value = v3.Value * scale
end
end
if isFileMesh then
parent.Scale = parent.Scale * scale
child.Value = child.Value * scale
end
end
end
end
for accessory: Accessory, _ in pairs(accessories) do
local handle: BasePart = accessory:FindFirstChildWhichIsA("BasePart")
handle.OriginalSize.Value = handle.OriginalSize.Value * scale
humanoid:AddAccessory(accessory)
end
humanoid.HipHeight = humanoid.HipHeight * scale
humanoidRootPart.CFrame = floorCF * CFrame.new(0, humanoidRootPart.Size.Y / 2 + humanoid.HipHeight, 0)
end
return rthroScaleFix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment