Hello developers, I am making a script that spawns NPCs when they click in the area. The problem I am having is the name of the NPC changing to every single one of them when the player changes its name.
Here is the video showing this:
Please scroll down until you see the function that changes the textbox (spawnNPC)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local localPlayer = Players.LocalPlayer
local mouse = localPlayer:GetMouse()
local placeButton = script.Parent
local modelToPlace = ReplicatedStorage:WaitForChild("Noob")
local placingEnabled = false
local previewModel = nil
local connection = nil
local baseMinX = workspace:WaitForChild("Boundary_MinX", 5)
local baseMaxX = workspace:WaitForChild("Boundary_MaxX", 5)
local baseMinZ = workspace:WaitForChild("Boundary_MinZ", 5)
local baseMaxZ = workspace:WaitForChild("Boundary_MaxZ", 5)
if not baseMinX then
warn("Boundary_MinX failed to load!")
end
if not baseMaxX then
warn("Boundary_MaxX failed to load!")
end
if not baseMinZ then
warn("Boundary_MinZ failed to load!")
end
if not baseMaxZ then
warn("Boundary_MaxZ failed to load!")
end
print("baseMinX:", baseMinX)
print("baseMaxX:", baseMaxX)
print("baseMinZ:", baseMinZ)
print("baseMaxZ:", baseMaxZ)
local function isInsideBase(position)
if not baseMinX or not baseMaxX or not baseMinZ or not baseMaxZ then
warn("One or more boundary parts were not found. Placement checks may not work correctly.")
return true
end
local minX = baseMinX.Position.X
local maxX = baseMaxX.Position.X
local minZ = baseMinZ.Position.Z
local maxZ = baseMaxZ.Position.Z
return position.X >= minX and position.X <= maxX and position.Z >= minZ and position.Z <= maxZ
end
local maxPlacementHeight = 5
local function updatePreviewModel()
if previewModel then
local mousePos = UserInputService:GetMouseLocation()
local ray = workspace.CurrentCamera:ViewportPointToRay(mousePos.X, mousePos.Y)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {previewModel}
for _, part in ipairs(previewModel:GetDescendants()) do
if part:IsA("BasePart") then
part.CanCollide = false
end
end
local raycastResult = workspace:Raycast(ray.Origin, ray.Direction * 1000, raycastParams)
if raycastResult then
local groundPosition = raycastResult.Position
local previewOffset = 3
local potentialPosition = groundPosition + Vector3.new(0, previewOffset, 0)
if potentialPosition.Y <= maxPlacementHeight then
if isInsideBase(potentialPosition) then
previewModel:SetPrimaryPartCFrame(CFrame.new(potentialPosition))
end
else
local clampedPosition = Vector3.new(potentialPosition.X, maxPlacementHeight, potentialPosition.Z)
if isInsideBase(clampedPosition) then
previewModel:SetPrimaryPartCFrame(CFrame.new(clampedPosition))
end
end
else
previewModel:SetPrimaryPartCFrame(CFrame.new(Vector3.new(0, -1000, 0)))
end
end
end
local function onPlaceButtonClicked()
placingEnabled = not placingEnabled
if previewModel then
previewModel:Destroy()
previewModel = nil
end
if connection then
connection:Disconnect()
connection = nil
end
if placingEnabled then
script.Parent.UIStroke.Enabled = true
if modelToPlace then
previewModel = modelToPlace:Clone()
previewModel.Parent = workspace
for _, part in ipairs(previewModel:GetDescendants()) do
if part:IsA("BasePart") then
part.Transparency = 0.5
part.CanCollide = false
part.Anchored = true
end
end
updatePreviewModel()
connection = RunService.RenderStepped:Connect(updatePreviewModel)
else
warn("Model to place not found in ReplicatedStorage: Noob")
placingEnabled = false
end
else
script.Parent.UIStroke.Enabled = false
end
end
local clickThreshold = 0.3
local isMouseButtonDown = false
local mouseDownTime = 0
local currentlyInteractingNPC = nil
local function handleNPCDamage(npcModel)
local humanoid = npcModel:FindFirstChild("Humanoid")
if not humanoid then
warn("Humanoid not found in NPC:", npcModel:GetFullName())
return
end
print("Connected HealthChanged event for:", npcModel:GetFullName())
local originalColor = {}
local partsToColor = {}
for _, part in ipairs(npcModel:GetDescendants()) do
if part:IsA("MeshPart") or part:IsA("BasePart") then
partsToColor[part] = true
originalColor[part] = part.Color
end
end
humanoid.HealthChanged:Connect(function(oldHealth, newHealth)
print("HealthChanged event fired for:", npcModel:GetFullName(), "Old Health:", oldHealth, "New Health:", newHealth)
print("Damage detected for:", npcModel:GetFullName())
local startOffset = 0.2
local shakeTweenInfo = TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 3, false, 0)
for part in pairs(partsToColor) do
part.Color = Color3.fromRGB(255, 0, 0)
end
task.wait(0.5)
for part in pairs(partsToColor) do
if originalColor[part] then
part.Color = originalColor[part]
end
end
end)
end
FUNCTION THAT CHANGES THE TEXTBOX
local function spawnNPC()
if placingEnabled and previewModel then
local previewPosition = previewModel:GetPrimaryPartCFrame().Position
if isInsideBase(previewPosition) then
local newModel = modelToPlace:Clone()
local torso = newModel.Torso
newModel.Parent = workspace
newModel:SetPrimaryPartCFrame(previewModel:GetPrimaryPartCFrame())
local genders ={"Male", "Female"}
local maleNames = {"Liam", "Noah", "Oliver", "James", "Elijah", "Mateo", "Theodore", "Henry", "Lucas", "William", "Benjamin", "Levi", "Sebastian", "Jack", "Ezra", "Michael", "Daniel", "Leo", "Owen", "Samuel", "Hudson", "Alaxander", "Asher", "Luca", "Ethan", "John", "David", "Jackson", "Joseph", "Mason", "Luke", "Matthew", "Julian", "Dylan", "Elias", "Jacob", "Maverick", "Gabriel", "Logan", "Aiden", "Thomas", "Isaac", "Miles", "Grayson", "Santiago", "Anthony", "Wyatt", "Carter", "Jayden", "Ezekiel"}
local femaleNames = {"Olivia", "Emma", "Charlotte", "Amelia", "Sophia", "Mia", "Isabella", "Ava", "Evelyn", "Luna", "Harper", "Sofia", "Camila", "Eleanor", "Elizabeth", "Violet", "Scarlett", "Emily", "Hazel", "Lily", "Gianna", "Aurora", "Nora", "Chloe", "Ellie", "Mila", "Avery", "Layla", "Abigail", "Ella", "Isla", "Eliana", "Nova", "Madison", "Zoe", "Ivy", "Lucy", "Willow", "Emilia", "Riley", "Naomi", "Victoria", "Stella", "Elena", "Hannah", "Valentina", "Maya", "Zoey"}
local randomGender = math.random(1, #genders)
local randomGender2 = genders[randomGender]
if randomGender2 == "Male" then
local randomNames = math.random(1, #maleNames)
local randomNames2 = maleNames[randomNames]
local configuration = newModel:FindFirstChild("Configuration")
if configuration then
local genderValue = configuration:FindFirstChild("Gender")
local nameValue = configuration:FindFirstChild("Names")
if genderValue and genderValue:IsA("StringValue") then
genderValue.Value = "Male"
else
warn("Gender StringValue not found or is not a StringValue")
end
if nameValue and nameValue:IsA("StringValue") then
nameValue.Value = randomNames2
else
warn("Name StringValue not found or is not a StringValue")
end
else
warn("Configuration folder not found")
end
elseif randomGender2 == "Female" then
local randomNames = math.random(1, #femaleNames)
local randomNames2 = femaleNames[randomNames]
local configuration = newModel:FindFirstChild("Configuration")
if configuration then
local genderValue = configuration:FindFirstChild("Gender")
local nameValue = configuration:FindFirstChild("Names")
if genderValue and genderValue:IsA("StringValue") then
genderValue.Value = "Female"
else
warn("Gender StringValue not found or is not a StringValue")
end
if nameValue and nameValue:IsA("StringValue") then
nameValue.Value = randomNames2
else
warn("Name StringValue not found or is not a StringValue")
end
else
warn("Configuration folder not found")
end
end
local interactionPoint = Instance.new("Part")
interactionPoint.Name = "InteractionPoint"
interactionPoint.Size = Vector3.new(6, 5, 3)
interactionPoint.CFrame = newModel:GetPrimaryPartCFrame() * CFrame.new(0, 1, 0)
interactionPoint.Transparency = 1
interactionPoint.CanCollide = false
interactionPoint.Parent = newModel
if torso then
interactionPoint.CFrame = torso.CFrame * CFrame.new(0, torso.Size.Y / 2 + 1, 0)
local weldConstraint = Instance.new("WeldConstraint")
weldConstraint.Part0 = interactionPoint
weldConstraint.Part1 = torso
weldConstraint.Parent = interactionPoint
end
local clickDetector = Instance.new("ClickDetector")
clickDetector.Parent = interactionPoint
clickDetector.MaxActivationDistance = 100000
clickDetector.CursorIcon = "rbxasset://0"
local frame = script.Parent.Parent:WaitForChild("Frame")
local textBox = frame:WaitForChild("TextBox")
clickDetector.MouseClick:Connect(function(player, target)
if player == localPlayer then
local clickedDetector = interactionPoint:FindFirstChild("ClickDetector")
local currentNPC = clickedDetector.Parent.Parent
if currentlyInteractingNPC and currentlyInteractingNPC ~= currentNPC and
currentlyInteractingNPC.Configuration:FindFirstChild("Names").Value == currentNPC.Configuration:FindFirstChild("Names").Value then
return
end
local humanoid = currentNPC:FindFirstChild("Humanoid")
if humanoid then
humanoid:TakeDamage(5)
end
currentlyInteractingNPC = currentNPC
local TweenService = game:GetService("TweenService")
if frame then
frame.Visible = true
textBox.Text = newModel.Configuration.Names.Value
local targetPosition = UDim2.new(0.52, 0, 0.4, 0)
if frame.Position ~= targetPosition then
local initialPosition = UDim2.new(1.4, 0, 0.4, 0)
frame.Position = initialPosition
local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local positionTween = TweenService:Create(frame, tweenInfo, {Position = targetPosition})
positionTween:Play()
end
frame.Size = UDim2.new(0, 342, 0, 426)
textBox.FocusLost:Connect(function(enter)
currentlyInteractingNPC = currentNPC
local currentText = textBox.Text
if currentText and currentText ~= "" then
if currentlyInteractingNPC == currentNPC then
local config = newModel:FindFirstChild("Configuration")
if config then
local nameVal = config:FindFirstChild("Names")
if nameVal and nameVal:IsA("StringValue") then
nameVal.Value = currentText
end
end
end
end
end)
end
end
end)
local skinColours = {
Color3.fromRGB(255, 204, 153),
Color3.fromRGB(182, 146, 109),
Color3.fromRGB(79, 63, 47),
Color3.fromRGB(84, 67, 50),
Color3.fromRGB(255, 232, 185),
Color3.fromRGB(255, 232, 187),
Color3.fromRGB(63, 50, 37),
Color3.fromRGB(100, 90, 57),
Color3.fromRGB(173, 141, 113),
}
local pantsColours = {
Color3.fromRGB(172, 172, 172),
Color3.fromRGB(213, 213, 213),
Color3.fromRGB(156, 250, 255),
Color3.fromRGB(70, 51, 38),
Color3.fromRGB(202, 213, 168),
Color3.fromRGB(172, 123, 163),
Color3.fromRGB(134, 144, 172),
Color3.fromRGB(58, 51, 41),
Color3.fromRGB(26, 26, 26),
}
local shirtsColours = {
Color3.fromRGB(172, 172, 172),
Color3.fromRGB(157, 131, 172),
Color3.fromRGB(75, 75, 75),
Color3.fromRGB(128, 172, 121),
Color3.fromRGB(67, 60, 45),
}
local randomSkinColor = skinColours[math.random(1, #skinColours)]
local randomPantsColor = pantsColours[math.random(1, #pantsColours)]
local randomShirtsColor = shirtsColours[math.random(1, #shirtsColours)]
local torso = newModel:FindFirstChild("Torso")
local leftArm = newModel:FindFirstChild("Left Arm")
local rightArm = newModel:FindFirstChild("Right Arm")
local leftLeg = newModel:FindFirstChild("Left Leg")
local rightLeg = newModel:FindFirstChild("Right Leg")
local head = newModel:FindFirstChild("Head")
if leftArm then leftArm.Color = randomSkinColor end
if rightArm then rightArm.Color = randomSkinColor end
if head then head.Color = randomSkinColor end
if rightLeg then rightLeg.Color = randomPantsColor end
if leftLeg then leftLeg.Color = randomPantsColor end
if torso then torso.Color = randomShirtsColor end
local particle = ReplicatedStorage.SpawnEffect:Clone()
particle.Parent = newModel
particle.CFrame = newModel:GetPrimaryPartCFrame()
particle.CanCollide = false
for _, part in ipairs(newModel:GetDescendants()) do
if part:IsA("BasePart") then
part.CanCollide = false
part.Anchored = false
end
end
handleNPCDamage(newModel)
task.delay(1, function()
if particle and particle.Parent == newModel then
particle:Destroy()
newModel.Torso.CanCollide = false
end
end)
else
print("Cannot place model outside the base!")
end
end
end
local boolean = game.Workspace.Configuration:WaitForChild("Spawning")
mouse.Button1Down:Connect(function()
isMouseButtonDown = true
mouseDownTime = tick()
if placingEnabled and UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) then
game.Workspace.Configuration.Spawning.Value = true
while isMouseButtonDown and UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) and placingEnabled and previewModel do
spawnNPC()
task.wait(0.1)
end
else
game.Workspace.Configuration.Spawning.Value = false
end
end)
mouse.Button1Up:Connect(function()
isMouseButtonDown = false
local timeHeld = tick() - mouseDownTime
if placingEnabled and previewModel and timeHeld < clickThreshold then
spawnNPC()
end
end)
placeButton.MouseButton1Click:Connect(onPlaceButtonClicked)```