How is the Roblox Snapchat game made?

Hello!

I’m sure most of you of played (or heard) of the Roblox Snapchat game. I played it, and I’m really wondering how it is done. I thought maybe with ViewportFrames, but then I read a post made by Roblox talking about CaptureService, which doesn’t seem to be fully released yet.

So how exactly would I go about doing this? If you think you can answer, please let me know! Thank you and have a wonderful day! :slight_smile:

1 Like

Im not sure if they use CaptureService but here’s my guess:

  • They add a ViewportFrame
  • They get a couple items in the radius of the player
  • They add all of those to the ViewportFrame
  • When you click the “take screenshot” button it just sends that viewport GUI and its info to the recievwr

But it seems like CaptureService will make this much less of a hassle so I’d wait for the whole API to be finished

3 Likes

Thanks for your reply!

I thought about doing this for a horror game, but you can’t take pictures. You use it as a way to look inside rooms and hallways to see where the monsters are.

Would you possibly be able to help me achieve this?

2 Likes

Hmm I forgot if client-sided lighting effects are possibly but you could make add some sort of color-correction and make it kinda green.

Seems like you can can change lighting on the client

Actually could you describe what you’re trying to achieve in more detail?

2 Likes

What I want is whenever you equip a certain tool it enables the ViewportFrame so you can move it to view the areas around you. So say you’re coming up to a hallway and you don’t want to go down it yet. You equip this tool and move the camera in the frame so you can look down the hallway without getting in any possbile monsters eyesight. Does that make sense?

Here is the game I got inspired to make this by:
LifeTogether :house: RP [UPD15] - Roblox

2 Likes

Mb I’ve played LifeTogether before lol.

Uh this video will better explain than me. I guess you just update the stuff in the frame when the player moves

2 Likes

The video was very helpful! I’ve seen videos by this guy before and they’ve been very informative.

The problem with mine is that any clothes on my avatar don’t replicate. Is there anyway to fix that? Also, how do I make it where the frame updates in real-time. So if I jump, I see it in my ViewportFrame.

2 Likes

Do they not only replicate in the ViewportFrame or do they just not replicate overall?

I don’t think that updating the ViewportFrame every single time the player moves is kinda dumb. What you could do is detect when you jump and then just use a Body Mover and make your character move up

3 Likes

They don’t replicate in the ViewportFrame, as in I don’t have them.

I would prefer not to use BodyMovers as they are now deprecated, but if that is the best way, I can try to do that.

2 Likes

Mb I meant like AlignOrientation and AlignPosition

Hm there’s a function I’m pretty sure that gets the clothing ids and then you can apply them with another function… found em now

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid, HumanoidRootPart = Character:WaitForChild("Humanoid"), Character:WaitForChild("HumanoidRootPart")

-- ur code

local Desc = Humanoid:GetHumanoidDescriptionFromUserId(Player.UserId)
Humanoid:ApplyDescription(Desc)
2 Likes

I get an error:

Players.TabbyCat904.PlayerGui.SurfaceGui.LocalScript:28: attempt to index nil with 'GetHumanoidDescriptionFromUserId'

Here is my code:

local Gui = script.Parent
local ViewportCamera = Instance.new("Camera")
ViewportCamera.CFrame = Gui.Adornee.CFrame
ViewportCamera.FieldOfView = 80
Gui.ViewportFrame.CurrentCamera = ViewportCamera

local DetectZone: BasePart = Gui.Adornee.Parent.DetectionZone
local Prompt: ProximityPrompt = Gui.Adornee.Attachment.ProximityPrompt

local debounce = false

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid, HumanoidRootPart = Character:FindFirstChildWhichIsA("Humanoid"), Character:WaitForChild("HumanoidRootPart")

Prompt.Triggered:Connect(function()
	if debounce == true then return end
	debounce = true
	Prompt.Enabled = false
	Gui.ViewportFrame:ClearAllChildren()
	
	task.wait(1)
	local Parts = workspace:GetPartBoundsInBox(DetectZone.CFrame, DetectZone.Size)
	for _, part in Parts do
		local PartClone = part:Clone()
		PartClone.Parent = Gui.ViewportFrame
		
		local Desc = Humanoid:GetHumanoidDescriptionFromUserId(Player.UserId)
		Humanoid:ApplyDescription(Desc)
	end
	Prompt.Enabled = true
	debounce = false
end)
2 Likes

Oh shoot mb mb it’s actually

game.Players:GetHumanoidDescriptionFromUserId

/

-- added type checks since you seem to prefer them
local Players: Players = game:GetService("Players")

local Desc: HumanoidDescription = Players:GetHumanoidDescriptionFromUserId(UserId)
1 Like

For some reason, I get this error:

 Humanoid::ApplyDescription() can only be called by the backend server
2 Likes

Ah it’s because it can only be called on the server “backend server”.

Just send a remote to the server and get the info there (then apply it)

2 Likes

Can you help me with that? I’m really bad at handling RemoteEvents.

2 Likes

Sure thing. add the path to the remote at the top

-- add this here
local RemoteEvent = path.to.remote
-- THIS
local Gui = script.Parent
local ViewportCamera = Instance.new("Camera")
ViewportCamera.CFrame = Gui.Adornee.CFrame
ViewportCamera.FieldOfView = 80
Gui.ViewportFrame.CurrentCamera = ViewportCamera

local DetectZone: BasePart = Gui.Adornee.Parent.DetectionZone
local Prompt: ProximityPrompt = Gui.Adornee.Attachment.ProximityPrompt

local debounce = false

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid, HumanoidRootPart = Character:FindFirstChildWhichIsA("Humanoid"), Character:WaitForChild("HumanoidRootPart")

Prompt.Triggered:Connect(function()
	if debounce == true then return end
	debounce = true
	Prompt.Enabled = false
	Gui.ViewportFrame:ClearAllChildren()
	
	task.wait(1)
	local Parts = workspace:GetPartBoundsInBox(DetectZone.CFrame, DetectZone.Size)
	for _, part in Parts do
		local PartClone = part:Clone()
		PartClone.Parent = Gui.ViewportFrame
		RE:FireServer()
                -- if you want to add params u can
	end
	Prompt.Enabled = true
	debounce = false
end)

server-side:

local RE = path.to.remote

game.Players.PlayerAdded:Connect(function(Player)
   Player.CharacterAdded:Connect(function(Character)
        local Desc = game:GetService("Players"):GetHumanoidDescriptionFromUserId(Player.UserId)
		Humanoid:ApplyDescription(Desc)
     end)
end)

I’ll be awaiting your response…

1 Like

Could something like this work?

Client:

local Gui = script.Parent
local ViewportCamera = Instance.new("Camera")
ViewportCamera.CFrame = Gui.Adornee.CFrame
ViewportCamera.FieldOfView = 80
Gui.ViewportFrame.CurrentCamera = ViewportCamera

local RemoteEvent = game.ReplicatedStorage.RemoteEvent

local DetectZone: BasePart = Gui.Adornee.Parent.DetectionZone
local Prompt: ProximityPrompt = Gui.Adornee.Attachment.ProximityPrompt

local debounce = false

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid, HumanoidRootPart = Character:WaitForChild("Humanoid"), Character:WaitForChild("HumanoidRootPart")

Prompt.Triggered:Connect(function()
	if debounce == true then return end
	debounce = true
	Prompt.Enabled = false
	Gui.ViewportFrame:ClearAllChildren()
	
	task.wait(1)
	local Parts = workspace:GetPartBoundsInBox(DetectZone.CFrame, DetectZone.Size)
	for _, part in Parts do
		local PartClone = part:Clone()
		PartClone.Parent = Gui.ViewportFrame
		RemoteEvent:FireServer()
	end
	Prompt.Enabled = true
	debounce = false
end)

Server:

game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local HumanoidDesc: HumanoidDescription = game.Players:GetHumanoidDescriptionFromUserId(Player.UserId)
		local Humanoid = Character:FindFirstChildOfClass("Humanoid")
		Humanoid:ApplyDescription(HumanoidDesc)
	end)
end)
1 Like

yeh it could.

mb for the late response

1 Like

It didn’t work. :frowning:

Did I do anything wrong?

Here is my code.

Server:

game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local HumanoidDesc = game.Players:GetHumanoidDescriptionFromUserId(Player.UserId)
		local Humanoid = Character:FindFirstChildOfClass("Humanoid")
		Humanoid:ApplyDescription(HumanoidDesc)
	end)
end)

Client:

local Gui = script.Parent
local ViewportCamera = Instance.new("Camera")
ViewportCamera.CFrame = Gui.Adornee.CFrame
ViewportCamera.FieldOfView = 80
Gui.ViewportFrame.CurrentCamera = ViewportCamera

local RemoteEvent = game.ReplicatedStorage:WaitForChild("RemoteEvent")

local DetectZone: BasePart = Gui.Adornee.Parent.DetectionZone
local Prompt: ProximityPrompt = Gui.Adornee.Attachment.ProximityPrompt

local debounce = false

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid, HumanoidRootPart = Character:WaitForChild("Humanoid"), Character:WaitForChild("HumanoidRootPart")

Prompt.Triggered:Connect(function()
	if debounce == true then return end
	debounce = true
	Prompt.Enabled = false
	Gui.ViewportFrame:ClearAllChildren()
	
	task.wait(1)
	local Parts = workspace:GetPartBoundsInBox(DetectZone.CFrame, DetectZone.Size)
	for _, part in Parts do
		local PartClone = part:Clone()
		PartClone.Parent = Gui.ViewportFrame
		RemoteEvent:FireServer()
	end
	Prompt.Enabled = true
	debounce = false
end)
1 Like