[ModeSeven is a publicly avaliable font developed by Andrew Bulhak]
A new version of ACC has released! (v1.1)
https://create.roblox.com/store/asset/122494176172993/Advanced-Classic-Clothing-2D-layerable-clothing
Older Releases
advanced_classic_clothing_1.0.rbxm (8.5 KB)
What's new in V1.1 - 23.9.2025
I have now fixed the issue on R15 rigs where the clothing detail (on arms and legs) just disappear in the joints portion of the body part.
- Added method
getClothingTexturesFromBodyPartName(bodyPartName)
which returns all clothing textures from the given body part name - Added spritesheet data
jointsNegateOffsetR15
which allows the clothing textures to not stretch over R15 body joints
I had some free time and managed to reimplement how classic clothing is wrapped around a standard humanoid rig. And with that I present Advanced classic clothing!
This is also my first time open-sourcing something, Let me know if I should make some changes.
This modulescript brings in some QOL improvements for 2D classic clothing which can be used in game where flexible character creation is implemented. This eliminates the need to reupload the same piece of clothing with minor changes. This makes the old 2D classic clothing infinitely customisable and more expressive in my opinion.
Features include:
- Allow for classic clothing to layer on top of each other (with Zindex support)
- Overlap over the dreaded modesty layer for R15 rigs, (an unintentional feature)
- ANIMATE clothing by using
OffsetStudsU
andOffsetStudsV
- Ability to create custom profiles for different clothing e.g. 2D shoes, gloves, belts, etc
- Literally anything that the standard Texture property offers, excluding MaterialVariant
I wrote this entirely from scratch in around 4 days which means there are lots of bugs in issues listed under Known issues which I suggest you read first
BASIC USAGE - Get started
First you need to aquire Advanced Classic Clothing
Now, to use advanced classic clothing, you need to require it.
--[[
Type: Script/LocalScript
RunContext: Legacy/Client/Server
]]
local advanced_classic_clothing = require(path.to.advanced_classic_clothing)
To apply a clothing to a character model, you now need to create a new object:
- The first parameter is the name of the shirt, It can be anything you like.
- Second is the image Id of the shirt
- Third is a valid R6 or R15 character model
- and Finally the type of clothing. Defaults is “shirt” or “pants”. It is not case sensitive.
local shirt_id= "rbxassetid://119117418244968" -- Has to be an ImageID, not a clothing ID!!
local character = path.to.your.character
local new_shirt = advanced_classic_clothing.new("My_Shirt",shirt_id,character,"shirt")
Now the script detects and uses the correct spritesheet data for the specific humanoid and applies each face of the clothing image to the correct side of the bodyparts.
Now you should get this:
From now on I will continue with the R15 rig. Steps for blocky R6 is the same.
Now we want to add in the pants. You simply do advanced_classic_clothing.new()
again except you change the image Id to a pants image and set the clothingType to “pants”
local pants_id = "rbxassetid://77995515363451"
local new_pants = advanced_classic_clothing.new("My_Pants",pants_id,character,"pants")
Now you should get this:
Now you see the straps are overlapping over the jacket. Normal firefighting gear has the straps under the jacket. We can fix this by using the
ChangeZIndex
method stored in the advanced_classic_clothing object.
new_shirt:ChangeZIndex(1)
new_pants:ChangeZIndex(0)
--[[
above code is functionally the same as:
new_shirt:ChangeTextureProperty("ZIndex",1)
new_pants:ChangeTextureProperty("ZIndex",0)
]]
Now the shirt is on top of the textures for the pants torso, resulting to this:
Finally, we want to change the
property
of the texture. There is a method which takes in the name of the property which is part of the Texture class and allows us to change the value of it.
You can change the pants
transparency to 0.75
using this:
new_pants:ChangeTextureProperty("Transparency",0.75)
To delete the advanced_classic_clothing object but retain the clothing textures on the character you use:
new_shirt:DestroyMethods()
Doing so means that you can no longer change Texture properties or the ZIndex.
To remove the object and all the clothing textures:
new_shirt:Destroy()
--[[
This method uses the spritesheet_applicator's DestroyAllInstances()
method to remove any created sprites..
]]
And that’s it! You have basically mastered the arts of adding advanced classic clothing!
Final code
local advanced_classic_clothing = require( game:GetService("ReplicatedStorage"):WaitForChild("advanced_classic_clothing"))
local shirt_id= "rbxassetid://119117418244968"
local character = script.Parent
local new_shirt = advanced_classic_clothing.new("My_Shirt",shirt_id,character,"shirt")
local pants_id = "rbxassetid://77995515363451"
local new_pants = advanced_classic_clothing.new("My_Pants",pants_id,character,"pants")
new_shirt:ChangeTextureProperty("ZIndex",1)
new_shirt:ChangeZIndex(1)
new_pants:ChangeZIndex(0)
new_pants:ChangeTextureProperty("Transparency",0.75)
new_shirt:Destroy()
ADVANCED - Animate 2D clothing
I have not yet made a guide on how to modify the default spritesheet data (the script that contains sprite info), I would sure to do that later.
I have taken inspiration from this guide from the ROBLOX Docs which allows me to animate clothing and make some interesting effects.
I have created this cloud texture using PaintDotNet
and uploaded it as an image with the same resolution and aspect ratio as a clothing template. I then binded the movement to OffsetStudsU
to create this effect:
Now you can create your own animated retroslop
Code
local advanced_classic_clothing = require( game:GetService("ReplicatedStorage"):WaitForChild("advanced_classic_clothing"))
local shirt_id= "rbxassetid://113746328831574"
local character = script.Parent
local new_shirt = advanced_classic_clothing.new("My_Shirt",shirt_id,character,"shirt")
local pants_id = "rbxassetid://113746328831574"
local new_pants = advanced_classic_clothing.new("My_Pants",pants_id,character,"pants")
new_shirt:ChangeTextureProperty("ZIndex",1)
new_shirt:ChangeZIndex(1)
new_pants:ChangeZIndex(0)
local runservice = game:GetService("RunService")
local colour = Color3.new(0.666667, 1, 1)
new_shirt:ChangeTextureProperty("Color3",colour) -- light blue
new_pants:ChangeTextureProperty("Color3",colour)
function animate(deltatime,clothing_assets,studsPerTick)
local real = (1/60) / deltatime
for _,textures in clothing_assets do
if textures:IsA("Texture") then
textures.OffsetStudsU += (studsPerTick * real)
end
end
end
local shirt_assets = new_shirt:getAllClothingTextures()
local pants_assets = new_pants:getAllClothingTextures()
runservice.Heartbeat:Connect(function(dt)
animate(dt,shirt_assets,0.01)
animate(dt,pants_assets,-0.01)
end)
How it works
This takes a standard classic clothing template and uses Texture
instances to recreate each side of a body part with the applied clothing.
I used my spritesheet modulescript which converts bitmap pixels into Roblox studs and applies its offsets and sizes to a texture accordingly. (It does this by taking the 2D size of an object and the resolution of the target spritesheet image)
The main script reads a table containing the name of the bodypart where it then contains information on how and where to apply the faces of a 2D clothing asset to that bodypart.
API Methods
Method/Constructor Name | Method Description |
---|---|
new(name : string,imageId,humanoidModel : Humanoid,clothingType : string,optional_spriteSheetdata : string) : advanced_clothing_object | Creates a new advanced_classic_clothing object (optional_spriteSheetdata is only needed if you want to force another spritesheet) |
ChangeTextureProperty(property : string,value : any) : nil | Changes the texture property using its name and applies it with the specified value |
ChangeZIndex(zindex : number) : nil | Change the ZIndex value for all the texture instances |
getClothingType() : string | Returns the clothing type parsed in new() |
getAllClothingTextures() : {} | Returns a cloned table containing all the Textures that make up the clothing |
[V1.1] getClothingTexturesFromBodyPartName(bodyPartName : string) : {} | Returns all clothing textures (if any) from the given body part name |
DestroyMethods() : nil | Destroys the advanced_classic_clothing object but keeps the textures (effectively making it read-only) |
Destroy() : nil | Same as DestroyMethods but removes all clothing textures |
Example explanation
In the example I used my firefight
(fire fighter) outfit I have saved on ROBLOX, mainly because I have the original .pdn
files that made up those clothing assets.
The pants and shirt images are split into different layers. From the base clothing background to the sowlines and even to small details e.g. the radio and uniform nameplate.
Each of the layered images are first converted to a Normal image by setting the image to black and white and whacking the brightness up. This is done to allow me to change the colour of the clothing. Of course, some parts (notabally the boots above the ankles) would remain black, if I don’t want players to change to colour of that.
Each of those layers get their own advanced_layerable_clothing
object where from there contains methods
to modify all it’s Texture properties, from the image colour, transparency and even the ZIndex.
Known issues
- (R6) Blocky rig clothing does not wrap around the beveled edges
- This is because the Texture property thinks there is no mesh applied which results to it not wrapping properly. Purely a visual bug and if your game aesthetic don’t require beveled edges on characters, then this bug may be a feature for you.
- (R6) R6 with meshed parts has clothing displayed incorrectly
- Literally don’t even try, I even mentioned that the blocky R6 is only supported.
- (R15) Clothing parts look overstretched
- This has been resolved in V1.1!
- (R6 + R15) Some of the textures are rotated incorrectly
e.g. Feet treads are rotated heel first
- I can’t really find a fix for this, you might just rotate the problem bottom hands and feet faces up-side-down using an image editor.
- (R6 + R15) Clothing with alpha has sharper borders
- This is not really an issue, rather an unintentional feature (but I still feel the need to mention it), If you have a clothing asset that has transparent areas, you might find them to have a border around non-transparent parts of the image, It is just how the image resampler works when stretching an image that is not it’s native size. Bet they go well with the highlight property and create some anime-like borders.
Disadvantages
The biggest issue was writing down spritesheet profiles for the different rig types. R6 is easy to manage, however R15 took 350 lines of code (about twice as long as the main modulescript) and one entire night to complete. Thankfully, for both R6 and R15 I have written a default rig profile for you to read and make changes to.
There is also the issue with potentially spamming a bunch of textures into a small area. print(6 * 14) --84+ possible texture instances in r15!!!!
The majority of us may not feel the performance impact (even with a computer from 2011) but those who have low end devices may feel the performace impact this may present (though do correct me on that)
And even tho I mentioned R6 many times, I still don’t recommend it’s usage due to how severely limited; the mordern stuff that is just broken compared to R15. ROBLOX’s choice to depricate R6 is a whole other discussion.
Image gallery
The normal texturemap containing components of the shirt(Bug) Bottoms of hands and feet are rotated the wrong way
(Bug) Why you shouldn’t use ACC with R6 and MeshParts.
Standard shirt instance (left) and Advanced Classic Clothing (right). Notice how the details around sowlines and the reflectors are more sharper. Honestly gives out some Borderlands vibes to it. Also (bug) The upper arms seems to be stretched too much where the reflectors are now under the LowerArms.
Other useful/related resources:
- The *Proper* Way to Futureproof R6
- OP @SubtotalAnt8185 created a tutorial to apply R6 to R15. Also had issues applying 2D clothes to the custom rig although I haven’t personally tested yet
- 1.0 [Blocky] Layered Clothing - Resources
- Layered clothing using 3D models (UGC)
- And this model where I used the spritesheet applicator for the first time
*Because of ROBLOX’s excellent support for R6, this is only limited to the default (blocky) rig, and even that has some slight issues. Don’t worry, R15 is no better.
Hope this is useful!