Hard Written By Mark_GoodMan

Make a reflecting mirror Created on: 01-01-2020

Learn to make a working mirror reflecting you and others.

Introduction

Hello, my name is Mark_GoodMan , today i'll show you how to make a REALISTIC MIRROR, thanks to StillWater for this script, like a VERY BIG THANKS to him lol. Right, now let's get into making the MIRROR!

1. Making parts

I know this may be easy just by adding parts, but no, you need to change it's details correctly.

Now insert a models, then change it to "Mirror model", then insert "part in it, then scale the part to full size of map (as shwon in the images)





After it, now select it and go to properties and then change the following appearance (as shown in the images below).





2. Scripting mirrors

After you change the properties of the part, now go to StarterGui and insert "LocalScript"





After putting LocalScript in StarterGui, rename it to mirrors .

Now click on LocalScript (mirrors) and enter the following script:

-- StarterGUI:
-- LocalScript:
-- Name The LocalScript: mirrors

local player = game:GetService("Players").LocalPlayer
local character; repeat wait() character = player.Character until character
local camera = game:GetService("Workspace").CurrentCamera

local rs = game:GetService("RunService").RenderStepped
local reflections = require(script:WaitForChild("reflections"))

local mirrors = game:GetService("Workspace"):WaitForChild("Mirror model")

rs:connect(function()
	reflections:clearCharacters()
	local characters = {}
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		table.insert(characters, player.Character)
	end
	for _, mirror in pairs(mirrors:GetChildren()) do
		if mirror:IsA("BasePart") then
			reflections:drawWorld(mirror, game:GetService("Workspace"), {mirrors, unpack(characters)})
			reflections:drawCharacters(characters, mirror)
		end
	end
end)

-- Script by StillWater 

Now after you done putting the script into the LocalScript (mirrors), now right click on LocalScript and insert ModuleScript





After inserting ModuleScript, rename it to reflections .

Now click on ModuleScript (reflections) and enter the following script:

--// Declarations

local class = {}
local camera = game:GetService("Workspace").CurrentCamera

local renderPacket = {}

local reflections = Instance.new("Model", camera)
local users = Instance.new("Model", reflections)
local environment = Instance.new("Model", reflections)
reflections.Name = "reflections"
users.Name = "users"
environment.Name = "environment"

--// Functions

--[[
	Collects all items recursively in a certain class range.
	@param children: A table full of instances that the function will search
	@param class: The type of instance (IsA method used) that is required
	@param tab: If adding to another table this parameter may be used.
	@return A table containing all the instances that met the requirements.
--]]

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

--[[
	Collects all items recursively in a certain class range with a given instance ignore list (including decendants).
	@param children: A table full of instances that the function will search
	@param class: The type of instance (IsA method used) that is required
	@param ignores: Table of instances that can be ignored
	@return A table containing all the instances that met the requirements.
--]]

function gather_Ignores(children, class, ignores)
	local tab = {}
	for _, part in pairs(gather(children, class)) do
		local pass = true
		for _, thing in pairs(ignores) do
			if part == thing or part:IsDescendantOf(thing) then
				pass = false
			end
		end
		if pass then
			table.insert(tab, part)
		end
	end
	return tab
end

--// Methods

--[[
	Reflects item on local x axis.
	@param item: The instance (model or basepart) that will be reflected.
	@param against: The instance (basepart) that will be used as the reflection origin (mirror).
--]]

function class: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

--[[
	Reflects item on local x axis.
	@param item: The instance (model or basepart) that will be reflected.
	@param against: The instance (basepart) that will be used as the reflection origin (mirror).
--]]

function class:drawWorld(against, parent, ignores)
	table.insert(ignores, camera)
	local renders = gather_Ignores({parent}, "BasePart", ignores)
	renderPacket[against] = renderPacket[against] or {}
	for _, part in pairs(renders) do
		if (not part.Locked or part.Parent:IsA("Hat")) and part.Transparency < 1 then
			if not renderPacket[against][part] or renderPacket[against][part].cf ~= part.CFrame then
				if renderPacket[against][part] then
					renderPacket[against][part].focus:Destroy()
				end
				local focus = part:Clone()
				local joints = gather(focus:GetChildren(), "JointInstance")
				for _, joint in pairs(joints) do joint:Destroy() end
				focus.Anchored = true
				self:reflect(focus, against)
				focus.Parent = environment
				renderPacket[against][part] = {
					cf = part.CFrame;
					origin = part;
					focus = focus;
					event = part.AncestryChanged:connect(function() focus:Destroy() end);
				}
			end
		end
	end
end

function class:drawCharacters(characters, against)
	for _, character in pairs(characters) do
		character.Archivable = true
		local character = character:Clone()
		local hum = character:FindFirstChild("Humanoid")
		local scripts = gather(character:GetChildren(), "BaseScript")
		local parts = gather(character:GetChildren(), "BasePart")
		local joints = gather(character:GetChildren(), "JointInstance")
		if hum then
			hum.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
		end
		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
			self:reflect(part, against)
		end
		character.Parent = users
	end
end

function class:clearCharacters()
	users:ClearAllChildren()
end

function class:cleanup()
	environment:ClearAllChildren()
	users:ClearAllChildren()
	renderPacket = {}
end

return class

And after you pasted the script in the ModuleScript (reflections), your done, now try to run the game in studio, you should see yourself on the otherside of the mirrors as it follows all of your movements correctly, just like i did see myself, the script is still working btw.





yet this is script made by StillWater , shoutout to him. Also i'll be checking on this tutorial, so if the script is outdated or not working now, then i'll try to find a way to fix it Last time viewed this tutorial was 12/14/2019

Hard Written By Mark_GoodMan

See Mark_GoodMan's profile on Roblox

Discussion