NPC Chat System (Camera Malfunction)

Hi Everyone! My name is Beast and I am an intermediate level scripter. I started scripting about a year ago and I have come to think of it as an addictive hobby.

One downside to it is that scripting can cause some baaaaaad mental breakdowns, and I am on the verge of one, so please help.

Basically I have been creating an NPC chat system, where if F is pressed the NPC talks to you. It looks a little something like this:

Screenshot_600
Don’t mind the camera, fixing that as you are reading this.

I Have searched far and wide to find something even remotely similar to this, but have come back with nothing.

Basically what has been happening is when I open up a specific NPC’s gui, my personal NPC, the camera does this:

as you can see, I can move my character around and take the camera with me.
Script:

--Made by BEasTiO12 -- Admin World --  30/09/2020
-- NPC Chat System





-----------------------------------------------------------
-- Services


local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local Players = game:GetService("Players")




-----------------------------------------------------------
-- Main Variables


local DetectedNPC = nil
local Detected = false
local Chatting = false
local Skip = false
local Exit = false




-----------------------------------------------------------
-- Player


local Player = Players.LocalPlayer
local Camera = game.Workspace.CurrentCamera

local Gui = script.Parent
local Sounds = Gui.Sounds
local PromptLabel = Gui.PromptLabel
local LineLabel = Gui.LineLabel.LineLabel
local LineBG = Gui.LineLabel




-----------------------------------------------------------
-- Character


local Character = Player.Character or Player.CharacterAdded:Wait()
local CharHMR = Character:WaitForChild("HumanoidRootPart")




-----------------------------------------------------------
-- NPC


local NPCS = game.Workspace.NPCS:WaitForChild("Beast")




-----------------------------------------------------------
-----------------------------------------------------------
-- Functions


UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.X then -- X is the key to skip.
		if Chatting == true then
			Skip = true
			Sounds.Click:Play()
		end
	end
end)

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.Z then -- Z is the key to exit.
		if Chatting == true then
			Exit = true
			Sounds.Click:Play()
		end
	end
end)

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.F then -- Prompt is F.
		
		
		if Detected == true then
			local Lines = DetectedNPC:FindFirstChild("Lines")
			
			if Lines then
				Sounds.Click:Play()
				
				Chatting = true
				Detected = false
				
				LineLabel.Text = " "
				
				PromptLabel:TweenSize(UDim2.new(0, 0, 0, 0), "Out", "Linear", 0.1)
				LineLabel:TweenPosition(UDim2.new(0.229, 280,0.419, 0), "In", "Linear", 0.3)
				LineBG:TweenPosition(UDim2.new(0, 0, 0.6, 0), "In", "Linear", 0.3)
				
				wait(0.5)
				
				for i, Line in pairs(Lines:GetChildren()) do
					local Text = Line.Value
					
					for i = 1, #Text do
						LineLabel.Text = string.sub(Text, 1, i)
						Sounds.Talk:Play()
						if Skip == true then
							Skip = false
							LineLabel.Text = Text
							break
						end
						if Exit == true then
							break
						end
						wait(0.07)
					end
					if Exit == true then
						Exit = false
						break
					end
					repeat wait() until Skip == true or Exit == true
					Skip = false
				end
				
				Exit = false
				Skip = false
				
				PromptLabel:TweenSize(UDim2.new(0, 0, 0, 0), "Out", "Linear", 0.1)
				LineLabel:TweenPosition(UDim2.new(0, 0, 0, 0), "In", "Linear", 0.3)
				LineBG:TweenPosition(UDim2.new(0, 0, 1.2, 0), "In", "Linear", 0.3)
				
				wait(0.5)
				
				Chatting = false
				Detected = false
			end
		end
	end
end)




-----------------------------------------------------------
-----------------------------------------------------------
-- Main Loop


RunService.RenderStepped:Connect(function()
	
	
	if Detected == false and Chatting == false then
		for i, NPC in pairs(NPCS:GetChildren()) do
			local Humanoid = NPC:FindFirstChild("Humanoid") -- Possible Fault
			local HMR = NPC:FindFirstChild("HumanoidRootPart")
			
			if Humanoid and HMR then 
				if (HMR.Position - CharHMR.Position).magnitude < 10 then -- Distance from Tech
					Detected = true
					DetectedNPC  = NPC
					PromptLabel:TweenSize(UDim2.new(0.145, 0, 0.145, 0), "Out", "Linear", 0.1)
					print(DetectedNPC.name)
				end
			end
		end
		
	end
		
	if Detected == true and Chatting == false then
		local Humanoid = DetectedNPC:FindFirstChild("Humanoid")
		local HMR = DetectedNPC:FindFirstChild("HumanoidRootPart")
		local Head = DetectedNPC:FindFirstChild("Head")
		
		if Humanoid and HMR then 
			if (HMR.Position - CharHMR.Position).magnitude > 10 then
				Detected = false
				DetectedNPC = nil
				PromptLabel:TweenSize(UDim2.new(0, 0, 0, 0), "In", "Linear", 0.1)
				print("No Longer Detected NPC")
			else
				local WTSP = Camera:WorldToScreenPoint(Head.Position)
				PromptLabel.Position = UDim2.new(-0, WTSP.X, -0.1, WTSP.Y)
			end
		end
	end
	
	if Chatting == true then
		local Humanoid = DetectedNPC:FindFirstChild("Humanoid")
		local HMR = DetectedNPC:FindFirstChild("HumanoidRootPart")
		
		if Humanoid and HMR then 
			Camera.CameraType = Enum.CameraType.Scriptable
			Camera.CFrame = Camera.CFrame:Lerp(HMR.CFrame * CFrame.new(-4, 8, -10) * CFrame.fromOrientation(math.rad(-20), math.rad(255), -0.35), 0.05)
		end
	else
		Camera.CameraType = Enum.CameraType.Custom
	end
	
	
end)

This is becoming frustrating, as I don’t get what the problem is. It is a complete duplicate of the working script, just with the line local NPCS = game.Workspace.NPCS:WaitForChild(“Beast”) having a different target.

If you read this far, I thank you, and I hop you can help me out.

2 Likes

I really don’t understand the problem in the picture you provided. A simple paragraph that explains the problem will be greatly appreciated.

I think he means that the view on the screen when you click the NPC is not facing the NPC but showing the regular view.

I changed some lines from your code, hope it helps!

Note: You can set camera distance from NPC via changing distance value.

--Made by BEasTiO12 -- Admin World --  30/09/2020
-- NPC Chat System





-----------------------------------------------------------
-- Services


local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local Players = game:GetService("Players")




-----------------------------------------------------------
-- Main Variables


local DetectedNPC = nil
local Detected = false
local Chatting = false
local Skip = false
local Exit = false

local distance = 6 


-----------------------------------------------------------
-- Player


local Player = Players.LocalPlayer
local Camera = game.Workspace.CurrentCamera

local Gui = script.Parent
local Sounds = Gui.Sounds
local PromptLabel = Gui.PromptLabel
local LineLabel = Gui.LineLabel.LineLabel
local LineBG = Gui.LineLabel




-----------------------------------------------------------
-- Character


local Character = Player.Character or Player.CharacterAdded:Wait()
local CharHMR = Character:WaitForChild("HumanoidRootPart")




-----------------------------------------------------------
-- NPC


local NPCS = game.Workspace.NPCS:WaitForChild("Beast")




-----------------------------------------------------------
-----------------------------------------------------------
-- Functions


UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.X then -- X is the key to skip.
		if Chatting == true then
			Skip = true
			Sounds.Click:Play()
		end
	end
end)

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.Z then -- Z is the key to exit.
		if Chatting == true then
			Exit = true
			Sounds.Click:Play()
		end
	end
end)

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.F then -- Prompt is F.


		if Detected == true then
			local Lines = DetectedNPC:FindFirstChild("Lines")

			if Lines then
				Sounds.Click:Play()

				Chatting = true
				Detected = false

				LineLabel.Text = " "

				PromptLabel:TweenSize(UDim2.new(0, 0, 0, 0), "Out", "Linear", 0.1)
				LineLabel:TweenPosition(UDim2.new(0.229, 280,0.419, 0), "In", "Linear", 0.3)
				LineBG:TweenPosition(UDim2.new(0, 0, 0.6, 0), "In", "Linear", 0.3)

				wait(0.5)

				for i, Line in pairs(Lines:GetChildren()) do
					local Text = Line.Value

					for i = 1, #Text do
						LineLabel.Text = string.sub(Text, 1, i)
						Sounds.Talk:Play()
						if Skip == true then
							Skip = false
							LineLabel.Text = Text
							break
						end
						if Exit == true then
							break
						end
						wait(0.07)
					end
					if Exit == true then
						Exit = false
						break
					end
					repeat wait() until Skip == true or Exit == true
					Skip = false
				end

				Exit = false
				Skip = false

				PromptLabel:TweenSize(UDim2.new(0, 0, 0, 0), "Out", "Linear", 0.1)
				LineLabel:TweenPosition(UDim2.new(0, 0, 0, 0), "In", "Linear", 0.3)
				LineBG:TweenPosition(UDim2.new(0, 0, 1.2, 0), "In", "Linear", 0.3)

				wait(0.5)

				Chatting = false
				Detected = false
			end
		end
	end
end)




-----------------------------------------------------------
-----------------------------------------------------------
-- Main Loop


RunService.RenderStepped:Connect(function()


	if Detected == false and Chatting == false then
		for i, NPC in pairs(NPCS:GetChildren()) do
			local Humanoid = NPC:FindFirstChild("Humanoid") -- Possible Fault
			local HMR = NPC:FindFirstChild("HumanoidRootPart")

			if Humanoid and HMR then 
				if (HMR.Position - CharHMR.Position).magnitude < 10 then -- Distance from Tech
					Detected = true
					DetectedNPC  = NPC
					PromptLabel:TweenSize(UDim2.new(0.145, 0, 0.145, 0), "Out", "Linear", 0.1)
					print(DetectedNPC.name)
				end
			end
		end

	end

	if Detected == true and Chatting == false then
		local Humanoid = DetectedNPC:FindFirstChild("Humanoid")
		local HMR = DetectedNPC:FindFirstChild("HumanoidRootPart")
		local Head = DetectedNPC:FindFirstChild("Head")

		if Humanoid and HMR then 
			if (HMR.Position - CharHMR.Position).magnitude > 10 then
				Detected = false
				DetectedNPC = nil
				PromptLabel:TweenSize(UDim2.new(0, 0, 0, 0), "In", "Linear", 0.1)
				print("No Longer Detected NPC")
			else
				local WTSP = Camera:WorldToScreenPoint(Head.Position)
				PromptLabel.Position = UDim2.new(-0, WTSP.X, -0.1, WTSP.Y)
			end
		end
	end

	if Chatting == true then
		local Humanoid = DetectedNPC:FindFirstChild("Humanoid")
		local HMR = DetectedNPC:FindFirstChild("HumanoidRootPart")

		if Humanoid and HMR then 
			
			Camera.CameraType = Enum.CameraType.Scriptable
			Camera.CameraSubject = HMR
			
			Camera.CFrame = HMR.CFrame:ToWorldSpace(CFrame.new(0,0,-distance))
			Camera.CFrame = CFrame.new(Vector3.new(Camera.CFrame.X,Camera.CFrame.Y,Camera.CFrame.Z),HMR.Position)
			
		end
	else
		Camera.CameraType = Enum.CameraType.Custom
		Camera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid
	end


end)
1 Like

Basically in the first pictures, this guy was my first NPC. Now when i moved onto my next PC, I did the same thing, but switched around the code a bit. Now the problem is that instead of the camera being anchored to a specific position, it stays as the regular view.

You dont know how blessed u are.

So would this work if i was to transfer it to a different NPC?

I think it should work.

And if it didnt, what else would I have to change? (Besides local NPCS = game.Workspace.NPCS:WaitForChild(“Beast”))

I mean if you didn’t something wrong, the code will always work.