Display closest NPC in a ViewportFrame

I’m trying to make a ViewportFrame display the closest NPC, along with its health.

The problem is that it’s not working. I don’t see the NPC or the Camera underneath the ViewportFrame while playtesting and it doesn’t seem to be picking the closest NPC.

Here’s my code (LocalScript):

local plr = game.Players.LocalPlayer
local CurrentNPC = script.Parent.CurrentNPC
local npc_directory = game.Workspace.NPCs --put the name of the folder here
local lastNPC = 1
local function ClosestHumanoid(player)

	local npcs = npc_directory:GetChildren();

	local closest = { humanoid = false, distance = math.huge } --where we will store the closest humanoid found so far, along with how far away it is
	local character = player.Character or player.CharacterAdded:wait();
	local root = character:WaitForChild('HumanoidRootPart', 1);

	local to_check = npcs;

	for _,humanoid_model in pairs(to_check) do
		
		if humanoid_model:FindFirstChild("HumanoidRootPart") then
			local displacement = (humanoid_model.HumanoidRootPart.Position - root.Position).magnitude;
			if displacement < closest.distance then
				closest.distance = displacement;
				closest.humanoid = humanoid_model:FindFirstChild('Humanoid');
			end
		end
		

	end

	return closest.humanoid
end

function updateHealth(h:Humanoid)
	
	local p = h.Health / h.MaxHealth
	
	script.Parent.ViewportFrame.HealthBG.Bar.Size = UDim2.new(p,0,1,0)
	script.Parent.ViewportFrame.HealthBG.Bar.BackgroundColor3 = Color3.fromHSV(p* 0.3, 1, 1)
	
end
local c
function updatePreview()
	local closest = ClosestHumanoid(plr)
	
	if script.Parent.ViewportFrame:FindFirstChild("Camera") == nil then
		c = Instance.new("Camera", script.Parent.ViewportFrame)
		script.Parent.ViewportFrame.CurrentCamera = c
		c.CFrame = CFrame.new(0.0709295422, -145.504364, -4.38470221, -0.999869227, 1.60421878e-05, 0.0161744691, -1.81898919e-12, 0.999999583, -0.000991821289, -0.0161744766, -0.000991691602, -0.999868751)

	end
	 
	if CurrentNPC.Value ~= lastNPC then
		
		if script.Parent.ViewportFrame:FindFirstChild("NPCPreview") then
			script.Parent.ViewportFrame.NPCPreview:Destroy()
		end
		
		if closest then
			CurrentNPC.Value = closest.Parent
			lastNPC = CurrentNPC.Value
			local npcClone:Model = CurrentNPC.Value:Clone()

			npcClone.Parent = script.Parent.ViewportFrame
			npcClone.Name = "NPCPreview"
			npcClone:MoveTo(Vector3.new(0,-100,0))

			for i,v in pairs(npcClone:GetChildren()) do
				if v:IsA("BasePart") then
					v.Anchored = true
				end
			end





		end
	end
	
	
	
end

task.spawn(function()
	game:GetService("RunService").RenderStepped:Connect(function()

		if CurrentNPC.Value ~= nil then
			script.Parent.ViewportFrame.HealthBG.Visible = true
			updateHealth(CurrentNPC.Value.Humanoid)
		else
			script.Parent.ViewportFrame.HealthBG.Visible = false
		end
	end) --pee buckets for lunch pls mama cute 34
end)

game:GetService("RunService").RenderStepped:Connect(updatePreview)


1 Like

Ended up getting it to work!

chars

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.