Hello! I noticed that nobody has given a good tutorial on how to do this effect, leaving many to wonder if using ViewportFrames are their only option. I have come across a much simpler method which I will explain here.
What are ESP/Chams?
In this post, when I say "ESP/Chams" I am referring to the kind of "wall-hack" where you can distinctly see the silhouette of the object in question. Such as this:
Simple ESP / Chams Guide
For this effect you can create a Highlight instance either as a direct child of the target or with its Adornee property set to the target. It can be seen both directly and through walls.
I’m pretty sure you’re supposed to put Highlights in thePlayerGui, but I haven’t had any issues sticking them in a Model/Part in theworkspaceon the client side.
Occluded ESP / Chams Guide
How does it work?
Highlights behind other visible Highlights apparently do not get rendered. We can use this to “mask” the highlight that should only be seen behind obstructions.
To create this effect, you can make an object/model with a Highlight set to Occlude which will be the line-of-sight Highlight. Then, clone that object/model and set the new Highlight to AlwaysOnTop which will be the occlusion Highlight.
That is all you need to do to get this effect working. Here are some tips:
Perform size = size * 0.99 on the occlusion Instance to avoid z-fighting with the line-of-sight Highlight.
If you need the target to move around, use WeldConstraints to keep the occlusion Instance flush with the line-of-sight Instance.
You can set the line-of-sight Highlight FillTransparency to 0.999 to have no highlight on visible sections of the target (first picture in topic).
You can add the accessories to the occlusion Highlight as well, I just personally like this effect more.
Code
This is the script that generates Occluded Chams on the local Character.
I have also included an rbxl file if you would rather just jump in and see the effect.
note: this doesn’t handle first-person interactions with the highlights. Let me know if you want me to include how to do that in this guide.
local plr = game:GetService("Players").LocalPlayer
local chr = plr.Character or plr.CharacterAdded:Wait()
local chamsChr = Instance.new("Model")
chamsChr.Parent = workspace
chamsChr.Name = "ChamsChr"
for _, child in pairs(chr:GetChildren()) do
if not child:IsA("BasePart") then continue end
local cloned = child:Clone()
cloned.Parent = chamsChr
cloned:ClearAllChildren()
cloned.CanCollide = false
if cloned:IsA("MeshPart") then cloned.TextureID = "" end
cloned.Size = cloned.Size * 0.99 -- prevents z-fighting with the line-of-sight Highlight
local weld = Instance.new("WeldConstraint") -- weld the chams part to its corresponding part so it stays flush
weld.Parent = cloned
weld.Part0 = cloned
weld.Part1 = child
end
-- create the "line-of-sight Highlight"
local losHighlight = Instance.new("Highlight")
losHighlight.Parent = chr
losHighlight.DepthMode = Enum.HighlightDepthMode.Occluded
losHighlight.FillColor = Color3.new(1, 0, 0)
losHighlight.OutlineTransparency = 1
-- create the "occlusion Highlight"
local occHighlight = losHighlight:Clone()
occHighlight.Parent = chamsChr
occHighlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
occHighlight.FillColor = Color3.new(0, 0, 1)
occHighlight.FillTransparency = 0
You should be sure to make these effects on the client side so that it causes no server lag.
I will update this thread accordingly if I find more unique ways to use the Highlight instances in such a manner. Let me know if you have questions, feel that I didn’t explain something well enough, or have anything to add to this guide!
The word you’re looking for is “foolproof”, not reliable. I’m willing to say doing it with Highlights is much more reliable in every single way except for that one small drawback.
That issue can be mitigated quite easily. it’s not like you should have 31 highlight instances being displayed at any given time anyway. The most natural solution (using Occluded Chams as an example) would be to group all similar highlights into one model. For example, there would be a lineOfSightHighlight model and also an occlusionHighlight model. Then you just need 2 highlight instances in total for this system to work with as many players as you need (and you still have 29 highlight slots to work with).