I’ve recently had a want to turn my current mirror script to be server-sided, so that my game can be more secure from place-copying and such.
A couple of days ago, I successfully turned my old local mirror script (it’s a common script) to a server script by changing a few things, but I noticed some cons to this because it would become “jittery” and have very poor performance for players who have lower processing power. This is because the old script made a new clone of the player every RenderStepped and would destroy the old clone and immediately replace it with the new one.
Then I had an idea of cloning the player’s character once and only update the clone’s parts every RenderStepped so that it would fix this problem.
While working on this though, I got as for as cloning the player and tweaking some properties of the clone, because when it runs the reflect()
command (taken from the old script), it does nothing and does not produce any errors.
I couldn’t find anything wrong with it so I’ve taken it here. Am I doing something wrong, or is it just not compatible with being on the server-side?
local players = game:GetService("Players")
local workSpace = game:GetService("Workspace")
local heartBeat = game:GetService("RunService").Heartbeat
local reflection
local mirror = workSpace["Mirror model"].Part
local function reflect(item, against)
local cf = item:IsA("BasePart") and item.CFrame or item.PrimaryPart.CFrame
local x, y, z, r00, r01, r02, r10, r11, r12, r20, r21,r22 = against.CFrame:toObjectSpace(cf):components()
local newCf = against.CFrame:toWorldSpace(CFrame.new(-x ,y ,z , r00, -r01, -r02, -r10, r11, r12, -r20, r21, r22))
if item:IsA("BasePart") then
item.CFrame = newCf
if item:IsA("CornerWedgePart") then
item.Size = Vector3.new(item.Size.z, item.Size.y, item.Size.x)
item.CFrame = item.CFrame * CFrame.Angles(0,math.rad(90),0)
end
elseif item:IsA("Model") then
item:SetPrimaryPartCFrame(newCf)
end
end
local function gather(children, class, tab)
local tab = tab and tab or {}
for _, child in pairs(children) do
if child:IsA(class) then
table.insert(tab, child)
end
tab = gather(type(child) == "table" and child or child:GetChildren(), class, tab)
end
return tab
end
local function createReflection(character)
character.Archivable = true
reflection = character:Clone()
reflection.Name = character.Name.."\'s_reflection"
reflection.Humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
local scripts = gather(reflection:GetChildren(), "BaseScript")
local parts = gather(reflection:GetChildren(), "BasePart")
local joints = gather(reflection:GetChildren(), "JointInstance")
for _, src in pairs(scripts) do src:Destroy() end
for _, joint in pairs(joints) do joint:Destroy() end
for _, part in pairs(parts) do
part.Anchored = true
part.CanCollide = false
end
reflection.Parent = workSpace --<< Reflection Ready
end
local function mimicPlayer(character)
if reflection and character then
heartBeat:Connect(function()
local parts = gather(reflection:GetChildren(), "BasePart")
for i,v in pairs (parts) do
reflect(v, mirror)
end
end)
end
end
local function playerAdded(player)
player.CharacterAppearanceLoaded:Connect(function(character)
createReflection(character)
mimicPlayer(character)
end)
end
players.PlayerAdded:Connect(playerAdded)
Again, any help at all would help me a bunch!