You’ll need to clone your helmet model and apply each appearance to one model in Studio, then decide which helmet to give in your code. if it were me doing it, I’d create a folder in ServerStorage with all of them in it. I can put a bit of code together for it and edit it in.
An upside to this is that your code can be VERY short. Name the properly-textured helmet after the group rank number required to wear it and you can do your group rank checking in 3-5 lines of code.
Alright, How would i call that to the script, If I place it into say ServerStorage in a folder that says HelmetRanks would it be like Player.Character.Face1.Helmet1.HelmetRanks.Chiefs
local helmetRanks = game:GetService("ServerStorage").HelmetRanks
local surfaceAppearance = HelmetRanks["user helmet"]:Clone() -- should correspond with users rank
surfaceAppearance.Parent = Player.Character.Face1.Helmet1 -- Path according to the screenshot you gave, adjust if needed
Alright So Make a Folder inside of ServerStorage, and for the User Helmet that is the name of the SurfaceAppearance itself and I place this code up here instead of all that?
I suspect you’ll need a helmet for each rank. This is what I’ve got (I had to change some variable names to make them easier to track for me):
local helmets = game:GetService("ServerStorage").Helmets
--[[This is where you put all your helmets.
Each helmet should have a name that matches its rank
in your group - so the helmet for Fire Lieutenant would
be called "248". That lets you add new ranks easily
and cuts down on the amount of code you need.]]
function boop(Player)
if Player.Character:findFirstChild("Humanoid") ~= nil and Player.Character:findFirstChild("Face1") == nil then
local rank = Player:GetRankInGroup(4875042)
local rank_helmet_base = helmets:FindFirstChild(rank)
if rank_helmet_base==nil then
error("No helmet found for group rank "..rank..".")
end
local helmet = rank_helmet_base:Clone()
helmet.Parent = Player.Character
local C = helmet:GetChildren()
for i=1, #C do
if C[i].className == "Part" or C[i].className == "UnionOperation" then
local W = Instance.new("Weld")
W.Part0 = helmet.Middle
W.Part1 = C[i]
local CJ = CFrame.new(g.Middle.Position)
local C0 = helmet.Middle.CFrame:inverse()*CJ
local C1 = C[i].CFrame:inverse()*CJ
W.C0 = C0
W.C1 = C1
W.Parent = helmet.Middle
end
local Y = Instance.new("Weld")
Y.Part0 = Player.Character.Head
Y.Part1 = helmet.Middle
Y.C0 = CFrame.new(0, 0, 0)
Y.Parent = Y.Part0
end
local h = helmet:GetChildren()
for i = 1, # h do
if h[i].className == "Part" or h[i].className == "UnionOperation" then
h[i].Anchored = false
h[i].CanCollide = false
end
end
end
end
script.Parent.ClickDetector.MouseClick:connect(boop)
Yes, replace your Player.Character.Face1… code with what I gave or just use the code provided by @deggy as it’s a lot better not having that many if statements
You can do exactly the same thing for another item, just add a new folder (I’d call it “Shields”) and put all your duplicates there. And yes, it will still trigger when you click the helmet.
The way I’ve got it set up, you’d put the whole model in. You could change things around so it’s just the mesh and it might run a little faster, but let’s try to just get it working for now.
e: I think I misunderstood your “shield” request. The shield is part of the helmet? It would depend on what it is - if it’s just a decal, it’s easy, but if it’s a SurfaceAppearance you’ll have to change things around a little.
Show me the Explorer view of the helmet model expanded and I should be able to get it working. Is it a MeshPart for the Helmet, another MeshPart for the Shield, and then a BasePart called “Middle”?
Without being able to test myself, this is what I’ve got. The structure is two folders in ServerStorage, called Helmets and Shields, with a full set of MeshParts (one for each rank) in them for the Helmet and Shield pieces. You’ll need to set that up before it will work.
When the user clicks the helmet, the script checks their group rank. If it finds a helmet and shield corresponding to their rank (remember, helmets and shields need to be named the number of the rank they’re for), it puts those into the model, using the CFrame of the parts already there. It then removes the original pieces of the helmet, so it’s a replacement.
If the script doesn’t get a hit for the rank, it leaves those parts of the helmet alone and prints a yellow warning into the console, so your “base” helmet can be the default but if something is wrong with the rank checking code it’ll still let you know.
Then, it does all the welding and parenting to the player.
That should work. I’m going to be away for a bit, but feel free to put any problems in the thread and I’ll see them later.
local serverStorage = game:GetService("ServerStorage")
local model = script.Parent
local helmets = serverStorage.Helmets
local shields = serverStorage.Shields
function boop(Player)
if Player.Character:findFirstChild("Humanoid") ~= nil and Player.Character:findFirstChild("Face1") == nil then
local new_helmet = model:Clone()
local rank = Player:GetRankInGroup(4875042)
local rank_helmet_base = helmets:FindFirstChild(rank)
local rank_shield_base = shields:FindFirstChild(rank)
if rank_helmet_base then
local rank_helmet = rank_helmet_base:Clone()
rank_helmet.CFrame = new_helmet.Helmet1.CFrame
rank_helmet.Parent = new_helmet
new_helmet.Helmet1:Remove()
else
warn("No helmet found for group rank "..rank..".")
end
if rank_shield_base then
local rank_shield = rank_shield_base:Clone()
rank_shield.CFrame = new_helmet.Shield.CFrame
rank_shield.Parent = new_helmet
new_helmet.Shield:Remove()
else
warn("No shield found for group rank "..rank..".")
end
new_helmet.Parent = Player.Character
local C = new_helmet:GetChildren()
for i=1, #C do
if C[i].className == "Part" or C[i].className == "UnionOperation" then
local W = Instance.new("Weld")
W.Part0 = new_helmet.Middle
W.Part1 = C[i]
local CJ = CFrame.new(g.Middle.Position)
local C0 = new_helmet.Middle.CFrame:inverse()*CJ
local C1 = C[i].CFrame:inverse()*CJ
W.C0 = C0
W.C1 = C1
W.Parent = new_helmet.Middle
end
local Y = Instance.new("Weld")
Y.Part0 = Player.Character.Head
Y.Part1 = new_helmet.Middle
Y.C0 = CFrame.new(0, 0, 0)
Y.Parent = Y.Part0
end
local h = new_helmet:GetChildren()
for i = 1, # h do
if h[i].className == "Part" or h[i].className == "UnionOperation" then
h[i].Anchored = false
h[i].CanCollide = false
end
end
end
end
script.Parent.ClickDetector.MouseClick:connect(boop)
Unfortunately Im unable to send the model out. It’s a Purchased Model, and I cannot give it out to others as per the ToS of the company making them. The best I would be able to do is a discord call and screen sharing