Auto avatar size checker - Anti-mini/small avatar

(This is my first tutorial! There might be a few issues about how I word it!)

Tired of these small avatars ruining hitboxes for your games?

image

Well, you’ve come to the right place.

heres the backstory on why i did this and all code after

I was playing Doomspire Brickbattle today with a friend of mine and saw 2 small avatar players. I mean, its fine if you want a small avatar, but to gain a competetive advantage? No thank you! I left the game shortly after, but that gave me an idea;

How can I get rid of these small avatars?

So I started brainstorming.

You’re just here for the code right? Here it is.

-- Put this script in ServerScriptService or Workspace!

local normalYSize = 4.65 --i recommend setting this a bit higher than the height of a normal avatar with all size settings cranked down

local armParts = {
	"UpperArm",
	"LowerArm",
	"Hand"
}

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function()
		--get player's avatar as a model for size comparison
		
		local model = game.Players:CreateHumanoidModelFromUserId(plr.UserId)
		
		if model:WaitForChild("Humanoid").RigType == Enum.HumanoidRigType.R6 then model:Destroy() return end
		-- ugc characters only work in r15 (unless they're dynamic heads)

		for _, part in model:GetChildren() do
			if part:IsA("Accessory") then
				part:Destroy()
			end
		end

		print("needs check")
		model.Parent = workspace
		model.PrimaryPart.CFrame = CFrame.new(131072, 131072, 131072) -- move it farther away from the center of the ga- i mean experience
		--remove arms (stickbug and possibly other ugc avatars have long arms and short bodies)

		for _, part in armParts do
			model["Left"..part]:Destroy()
			model["Right"..part]:Destroy()
		end

		--size time

		local useless, size = model:GetBoundingBox()

		print(size.Y)

		if size.Y < normalYSize then
			print("avatar has failed the size check!")
			plr:Kick("Avatar size too small! Please make your avatar larger.")
		end
	end)
end)

All the code for the people who don’t want to go through the tutorial is above. Now, time to actually learn.

Plan it out

Not-so crucial, but sure.

We need to plan what the code will do.

  • The code will detect the Y axis size of a player.
  • The code will remove the arms of a player to get a more accurate size (arms can be longer than the body sometimes)
  • The code will kick the player if the avatar is too small. However, you can make it do whatever you want to.

Setting up the script

Setup a script! Simple, right?

Make a script (not to get confused with localscript) and put it in Workspace or ServerScriptService.

Name it anything! I’ll name mine “AntiSmallAvatarScript”.

image

Thats it!

Variables

You really need two, but whatever.

Open up the script first. Then, remove the print("Hello, World!"). The script should be blank.
Now, let’s add the variables.

normalYSize

The size threshold.

This is the Y axis size threshold that when exceeded, the script will do it’s thing.

local normalYSize = 4.65 --this is a bit lower than the height of a normal avatar with all size settings cranked down

armParts

You wont understand now but it’s for later.

Just copy this down for now, you’ll understand later.

local armParts = {
	"UpperArm",
	"LowerArm",
	"Hand"
}

That’s all for variables!

Code time!

Yeah!

Foundation

Everything has a foundation!

Start off with a PlayerAdded event, and a CharacterAdded event inside that event.

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function()
	--this is where all the code is going!
	end)
end)

If you’re asking why I don’t get the character parameter, it’s because we don’t really need it.
Next, we are going to get a model of the character by using CreateHumanoidModelFromUserId for the size comparison.

Let’s make sure this is R15, since UGC avatar only supports R15.

	if model:WaitForChild("Humanoid").RigType == Enum.HumanoidRigType.R6 then model:Destroy() return end

Next, we are going to get a model of the character by using CreateHumanoidModelFromUserId for the size comparison.

	local model = game.Players:CreateHumanoidModelFromUserId(plr.UserId)

Lastly, let’s parent it to workspace and move it far from the center of the game.

		model.Parent = workspace
		model.PrimaryPart.CFrame = CFrame.new(131072, 131072, 131072)

Now, time for the challenge that may seem hard for some people but is pretty simple.

Size

Hard part, unless…

We can achieve this by using a function called GetBoundingBox. This function returns the orientation and size of the model.
So, let us utilize it, shall we?

		local useless, size = model:GetBoundingBox()

This script doesn’t necessarily focus on how skinny an avatar is, just how short it is, so all we need is the Y axis of the model.

Comparison

Easy as pie!

Just a quick if statement, do whatever you want if it is true, but I will kick the player.

		if size.Y < normalYSize then
			print("avatar has failed the size check!")
			plr:Kick("Avatar size too small! Please make your avatar larger.")
		end

And we are do-

wait…

Somethings wrong.

I thought this tutorial worked!

This is the outputted player size.
image
The avatar used was apparently ~3.5 studs tall without animations.

This got me a bit stuck.
I was struggling there, analyzing the avatar.
But something saves me from being stuck on this problem.

It’s the…
Object hightlight?

image

Might sound funny, but it’s true.
I accidentally put my mouse on it, and something comes up.

image

The arms are longer than they appear!
This is quite the simple fix. Before the check, we remove the arms (and accessories that might increase height) to get the true size. This was the purpose of the armParts variable we made.

Simple fix.

		for _, part in armParts do
			model["Left"..part]:Destroy()
			model["Right"..part]:Destroy()
		end

		for _, part in model:GetChildren() do
			if part:IsA("Accessory") then
				part:Destroy()
			end
		end
--if statement here!!! make sure to put the code before the if statement!!!

Now, will this actually work?

Only one way to find out.

Test time!!!

You better impress me.

I bought this smallest avatar set I found on youtube that costed 150 robux and put it on.

The result…

It works!

Thank’s for reading this tutorial! I hope you learned or found something you need!

16 Likes

Also does the head count for the size?

2 Likes

Instead of kicking, is it possible to resize the character and a menu pops up saying “Avatar was too small.”

4 Likes

Theoretically, it could be possible. I first thought about removing the UGC avatar package and replacing it with a default character. However, it seems really hard since the character is reshaped with avatar packages (UpperTorso can be tilted, resized, etc. and so can other parts). I have some new ideas in mind that I’ll try out in a bit.

Resizing the character, however, might actually be simpler. R15 characters can be rescaled with these three HumanoidDescription properties.
image

You could probably use the CreateHumanoidModelFromDescription to remake the character and set it as the actual character model. I’ll also try this method out soon and try to give a solution.

2 Likes

It does count head for size. If you don’t want it to count the head, put a model.Head:Destroy() before the if statement at the end of the script, like this.

model.Head:Destroy()
--if statement here
3 Likes

I found a solution.

Sadly, it doesn’t resize the avatar. I was having problems with that since characters don’t come with HumanoidDescriptions, which are needed to change the size of the avatar, so I thought more about it.

The script will now replace the character with a HumanoidDescription replacement, and then will tell a localscript via RemoteEvent that the player didn’t pass the check.

local normalYSize = 4.65 --i recommend setting this a bit lower than the height of a normal avatar with all size settings cranked down

local armParts = {
	"UpperArm",
	"LowerArm",
	"Hand"
}

local popupMessageEvent = game.ReplicatedStorage.MessagePopup
local humanoidDescriptionReplacement = game.ReplicatedStorage.HumanoidDescriptionReplacement

--  ^^ change these to where the event and humanoidDescriptionReplacement is ^^

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function()
		--get player's avatar as a model for size comparison

		local model = game.Players:CreateHumanoidModelFromUserId(plr.UserId)

		if model:WaitForChild("Humanoid").RigType == Enum.HumanoidRigType.R6 or plr.CanLoadCharacterAppearance == false then model:Destroy() return end
		-- ugc characters only work in r15 (unless they're dynamic heads)

		for _, part in model:GetChildren() do
			if part:IsA("Accessory") then
				part:Destroy()
			end
		end

		print("needs check")
		model.Parent = workspace
		model.PrimaryPart.CFrame = CFrame.new(131072, 131072, 131072) -- move it farther away from the center of the ga- i mean experience
		--remove arms (stickbug and possibly other ugc avatars have long arms and short bodies)

		for _, part in armParts do
			model["Left"..part]:Destroy()
			model["Right"..part]:Destroy()
		end

		--size time

		local useless, size = model:GetBoundingBox()

		print(size.Y)

		if size.Y < normalYSize then
			warn("avatar has failed the size check!")
			plr.CanLoadCharacterAppearance = false
			plr:LoadCharacterWithHumanoidDescription(humanoidDescriptionReplacement)
			popupMessageEvent:FireClient(plr, { -- edit the message using the diagram at the end of this reply.
				Title = "Avatar check has failed";
				Text = "Your avatar has failed the size check, please equip a larger avatar and rejoin to try again.";
				Duration = 5
			})
		end
	end)
end)

We also need a LocalScript in StarterGui (or StarterPlayerScripts).

Here’s the code for the LocalScript.

local startergui = game:GetService("StarterGui")
local event = game:GetService("ReplicatedStorage"):WaitForChild("MessagePopup")

event.OnClientEvent:Connect(function(options)
	startergui:SetCore("SendNotification", options)
end)

Use the following diagram to edit the message at the end of the script.

Lastly, add a remote event called “MessagePopup” and a HumanoidDescription called “HumanoidDescriptionReplacement” in ReplicatedStorage. Customize the HumanoidDescriptonReplacement to your liking! I made mine basic.
image

I hope this solves your problem!

2 Likes

Is there a way to detect skinniness? for example, the paper-like package?
image

2 Likes

You shouldnt count head since the head doesnt count as a hitbox so i think it should also prioritize hitboxes.

1 Like

Couldnt a player bypass this by having a big avatar and then changing it to a small avatar?

1 Like

depth?

That’s why it’s in a CharacterAdded function.
Everytime the Character property of the player changes (which also counts for reseting, reloading character, etc.) it performs a check again.

well yea. That’s exactly what I meant. But then I find out that the arms and legs have the exact same hitbox, except the mesh looks tiny.

i just did this to track both y or z axis

image

There are a couple of rthro characters that don’t change their hitbox and make depth a bit useless, but mini avatars (like plushy avatars) are most likely to be detected, except for rthro mini avatars.

1 Like

I used this with the stick bug package with the “Classic” scale applied, and it still let the body type pass the check…

I ended up creating my own system to detect these.
Anti-Stick Bug / Other Avatar Types with Busted Hitboxes System - Resources / Community Resources - Developer Forum | Roblox