Heya!
I followed the steps, but it ended up not working because the Positions were given as nil… So, as a test, I tried using AI to enhance it, and it told me to do some things:
AI Response
- Initial Issues:
- Your script threw errors indexing
nil values.
- The fade system was fading the wrong models or parts.
- You weren’t sure which part to use as the model’s
PrimaryPart.
- The high-detail parts were invisible by default, and low-detail parts never changed.
- Key Fixes and Improvements:
- Added an invisible, anchored “Anchor” part as PrimaryPart for each model so distance calculation is stable and consistent.
- Set initial transparency: Low parts visible, High parts invisible.
- Fixed fade logic so High fades in near the player, Low fades out, and vice versa when far.
- Added debug suggestions to verify model structure and script execution.
- Adapted the full system to your exact folder structure with
High and Low folders inside each model.
- Explained the difference between server and client (StarterCharacterScripts) context: Anchor creation must be done on the server; fading logic can run locally on each player’s character.
- Final Deliverables:
- A server script to create Anchors and assign PrimaryParts on all relevant models in Workspace.
- A StarterCharacterScripts client script to run the fading logic per player smoothly and efficiently.
StarterCharacterScripts (as a LocalScript):
local fadeModels = workspace:WaitForChild("DistanceDepended")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local fadeDistance = 50
local fadeDuration = 1
local activeFades = {}
local char = script.Parent
local hrp = char:WaitForChild("HumanoidRootPart", 5)
if not hrp then
error("HumanoidRootPart not found")
end
-- Initialize active fades for each model
for _, model in pairs(fadeModels:GetChildren()) do
if model:IsA("Model") then
activeFades[model] = {}
-- Set initial visibility assuming server set PrimaryPart and initial transparency
local low = model:FindFirstChild("Low")
local high = model:FindFirstChild("High")
if low then
for _, part in pairs(low:GetDescendants()) do
if part:IsA("BasePart") then
part.Transparency = 0
end
end
end
if high then
for _, part in pairs(high:GetDescendants()) do
if part:IsA("BasePart") then
part.Transparency = 1
end
end
end
end
end
local function fadeModel(model, direction)
if activeFades[model] == nil then
activeFades[model] = {}
end
if #activeFades[model] > 0 then return end
local showModel = model:FindFirstChild(direction == "In" and "High" or "Low")
local hideModel = model:FindFirstChild(direction == "In" and "Low" or "High")
if not showModel or not hideModel then
warn("Missing High/Low in model:", model.Name)
return
end
for _, part in pairs(showModel:GetDescendants()) do
if part:IsA("BasePart") then
local tween = TweenService:Create(part, TweenInfo.new(fadeDuration), {Transparency = 0})
table.insert(activeFades[model], tween)
tween:Play()
task.spawn(function()
tween.Completed:Once(function()
table.remove(activeFades[model], table.find(activeFades[model], tween))
end)
end)
end
end
for _, part in pairs(hideModel:GetDescendants()) do
if part:IsA("BasePart") then
local tween = TweenService:Create(part, TweenInfo.new(fadeDuration), {Transparency = 1})
table.insert(activeFades[model], tween)
tween:Play()
task.spawn(function()
tween.Completed:Once(function()
table.remove(activeFades[model], table.find(activeFades[model], tween))
end)
end)
end
end
end
local function checks()
for _, model in pairs(fadeModels:GetChildren()) do
if not model.PrimaryPart then continue end
local distance = (model.PrimaryPart.Position - hrp.Position).Magnitude
if distance >= fadeDistance then
fadeModel(model, "Out")
else
fadeModel(model, "In")
end
end
end
task.delay(2, function()
checks()
RunService:BindToRenderStep("LOD_Fade", Enum.RenderPriority.Last.Value, checks)
end)
ServerScriptService:
local fadeModels = workspace:WaitForChild("DistanceDepended")
for _, model in pairs(fadeModels:GetChildren()) do
if model:IsA("Model") then
-- Remove existing PrimaryPart and Anchor
model.PrimaryPart = nil
local oldAnchor = model:FindFirstChild("Anchor")
if oldAnchor then oldAnchor:Destroy() end
-- Create invisible Anchor part
local anchor = Instance.new("Part")
anchor.Name = "Anchor"
anchor.Size = Vector3.new(1,1,1)
anchor.Anchored = true
anchor.CanCollide = false
anchor.Transparency = 1
anchor.Position = model:GetModelCFrame().Position
anchor.Parent = model
model.PrimaryPart = anchor
end
end
(Keeping in mind, I still followed the folder structure and organization from you, @talis783)
It did manage to make what I wanted, but now, I’m starting to wonder from other perspectives if this can be optimized… 
Still, thanks for the help and to everyone else so far in this thread! 