NPC Interaction

I have made an NPC interaction system and i would like your Feedback about what all i should improve in it and any flaw in the NPC.
Here is an image of the NPC interaction.
NPC
You can also test the NPC in the game if u want
https://www.roblox.com/games/5165023127/Break
If u would like to buy this u can message me here or DM me on Discord Shenoy_Scripts#1182
Thank You for reading :slight_smile:

5 Likes

Very good maybe try improving the gui a little bit its too big

1 Like

Thank You and i will try to improve the UI :slight_smile:

The dialog is a bit too big! I would recommend probably like a cut scene of them talking and options for the player to say to them!

Can i Get Source Code? What does NPC stand for

1 Like

Does the npc work on mobile? If not, try making it work on mobile. The text box feels like it’s off somehow. I don’t know how.

3 Likes

short for nonplayer character.

“characters can sell things to NPCs to get money”

Currently it doesnt work on mobile i will add mobile support soon. :slightly_smiling_face:

Here is the source code

-- by Shenoy6--
 
-- Services --
 
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
 
--Main Variables
 
local  DetectedNpc = nil
local Detected = false
local Chatting = false
local Skip = false
local Exit = false
 
-- player --
local Player = game.Players.LocalPlayer
local Camera = game.Workspace.CurrentCamera
 
local GUI = script.Parent
local Sounds = GUI.Sounds
local PromptLabel = GUI.PromptLabel
local LineLabel = GUI.LineLabel
 
local Character = Player.Character or Player.CharacterAdded:Wait()
local CharHRP =  Character:WaitForChild("HumanoidRootPart")
 
--NPC--
 
local NPCS = game.Workspace:WaitForChild("NPCs")
 
-- functions--
 
UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.X then
		if Chatting == true then
			Skip = true
			Sounds.Click:Play()
		end
	end
end)
 
UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Z then
		if Chatting == true then
			Exit = true
			Sounds.Click:Play()
		end
	end
end)
 
UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.E then
 
		if Detected == true then
			print("Detects")
			local Lines = DetectedNpc:FindFirstChild("Lines")
			print("Working gg")
			if Lines then
				Sounds.Click:Play()
				Chatting = true
				Detected = false
 
				LineLabel.Text = " "
				PromptLabel:TweenSize(UDim2.new(0,0,0,0),"Out","Linear")
				LineLabel:TweenPosition(UDim2.new(0,0,0.8,0),"In","Linear")
 
				wait(.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")
				LineLabel:TweenPosition(UDim2.new(0,0,1.2,0),"Out","Linear")
 
				wait(.5)
 
				Chatting = false
				Detected = false
				print("Works")
			end
		end
	end
end)
-- Main Loop
 
RunService.RenderStepped:Connect(function()
	print(Detected)
	if Detected == false and Chatting == false then
		print("detected")
		for i , NPC in pairs(NPCS:GetChildren()) do
			local Humanoid = NPC:FindFirstChild("Humanoid")
			local HRP = NPC:FindFirstChild("HumanoidRootPart")
 
			if Humanoid and HRP then
				if (HRP.Position - CharHRP.Position).magnitude < 15 then
					Detected = true
					DetectedNpc = NPC
					PromptLabel:TweenSize(UDim2.new(0,60,0,60),"In","Linear")
					print(DetectedNpc.Name)
				end
			end
		end
	end
	if Detected == true and Chatting == false then
		print("not chatting")
		local Humanoid = DetectedNpc:FindFirstChild("Humanoid")
		local HRP = DetectedNpc:FindFirstChild("HumanoidRootPart")
 
		if Humanoid and HRP then
			if (HRP.Position - CharHRP.Position).magnitude > 15 then
				Detected = false
				DetectedNpc = nil
				PromptLabel:TweenSize(UDim2.new(0,0,0,0),"Out","Linear")
				print("No longer Detected NPC")
			else
				local WISP = Camera:WorldToScreenPoint(HRP.Position)
				PromptLabel.Position = UDim2.new(0, WISP.X, 0 , WISP.Y)
			end
		end
	end
 
	if Chatting == true then
		print("Chats")
		local Humanoid = DetectedNpc:FindFirstChild("Humanoid")
		local HRP = DetectedNpc:FindFirstChild("HumanoidRootPart")
 
		if Humanoid and HRP then
			Camera.CameraType = Enum.CameraType.Scriptable
			Camera.CFrame = Camera.CFrame:Lerp(HRP.CFrame * CFrame.new(-4,4,-7)* CFrame.fromOrientation(math.rad(-20),math.rad(215),0),0.07)
		end
	else
		Camera.CameraType = Enum.CameraType.Custom	
	end
end)
1 Like

Looks really cool, i’d say the only problem is you can do things like this…


So either make the npc and camera rotate to face the player.
or make the plaayeer walk to the right position
or make it so you can only activate it from the front.

Also “x” is a bit weird - i’d just keep using “e” or anykey would probs work well

Also im not the best scripter so take what i say with a grain of salt but it seems the process you are using may cause lots of lag if you have many npc’s

RunService.RenderStepped:Connect will run every frame, i dont think we need to run the check that often and doing so may slow down your game. It might be better to put a local script in the player scripts which activates on user inputting “e” and then runs a speech script depending on player position?
or pressing e fires a raycast then triggers script depending on what it hits.

Either way dont bother rewriting stuff unless it lags, just thought i’d say…

Also anchor the player character while you are talking…

But anyways looks really cool!

Thats a good Opinion, I will try to work on that .Also i would prefer to stick with “x” or add a button to it because when we press “e” the ui tween will happen.