How would I create cafe NPCs?

Hey there,

How would I make NPC’s that come up to the registers, staff can take their order (with ProximityPrompts), then they prepare it and get staff points. Thanks!

@CookieTechAi Do you know how’d I’d achieve this?

Yes, I can help you with that!

Here’s what you can do:

  1. Create an NPC model (or import one from the Toolbox) and add a Humanoid and a ClickDetector to it.

  2. Place the NPC at the register location.

  3. Create a script that detects when a player clicks on the NPC’s ClickDetector.

  4. When the player clicks on the NPC, create a ProximityPrompt that asks the player what they want to order.

  5. Store the player’s order in a table or datastore.

  6. When the order is complete, give the player staff points.

Here’s some sample code to get you started:

-- Define the NPC and the ProximityPrompt
local npc = workspace.NPC
local prompt = Instance.new("ProximityPrompt")
prompt.Parent = npc
prompt.ActionText = "Place your order"

-- Define a function to handle the player's order
local function handleOrder(player)
    -- Open a dialog to collect the player's order
    local order = game:GetService("TeleportService"):TeleportPlaceAsync(ORDER_DIALOG_ID, player)

    -- Store the order in a datastore
    local datastore = game:GetService("DataStoreService"):GetDataStore("orders")
    datastore:SetAsync(player.UserId, order)

    -- Give the player staff points when the order is complete
    local points = 10 -- Change this to the number of points you want to give
    game:GetService("PointsService"):AwardPoints(player.UserId, points)
end

-- Detect when a player clicks on the NPC's ProximityPrompt
prompt.Triggered:Connect(function(player)
    handleOrder(player)
end)

I hope this helps! Let me know if you have any questions.

This helps, but I’m wanting the NPC to order and the player to take the order

My apologies for misunderstanding your question earlier. Here’s how you can achieve what you’re looking for:

  1. Create an NPC model and add a Humanoid and a ClickDetector to it.

  2. Place the NPC at the register location.

  3. Create a script that detects when a player clicks on the NPC’s ClickDetector.

  4. When the player clicks on the NPC, create a ProximityPrompt that says “Take Order” and make it only visible to staff member players.

  5. When a staff member player clicks on the ProximityPrompt, create a dialog to ask the NPC for their order.

  6. Store the NPC’s order in a table or datastore.

  7. When the order is complete, give the staff member player staff points.

Here’s some sample code to get you started:

-- Define the NPC and the ClickDetector
local npc = workspace.NPC
local clickDetector = npc:FindFirstChildOfClass("ClickDetector")

-- Define the ProximityPrompt and make it visible only to staff members
local prompt = Instance.new("ProximityPrompt")
prompt.Parent = npc
prompt.ActionText = "Take Order"
prompt.RequiresLineOfSight = false
prompt.MaxActivationDistance = 5
for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
    if player:IsInGroup(STAFF_GROUP_ID) then -- Change this to your staff group ID
        prompt.PlayersIgnoringDistance = player
    end
end

-- Define a function to handle the staff member player's interaction with the NPC
local function handleStaffInteraction(player)
    -- Open a dialog to collect the NPC's order
    local order = game:GetService("TeleportService"):TeleportPlaceAsync(NPC_ORDER_DIALOG_ID, player)

    -- Store the order in a datastore
    local datastore = game:GetService("DataStoreService"):GetDataStore("orders")
    datastore:SetAsync("npc_order", order)

    -- Give the staff member player staff points when the order is complete
    local points = 10 -- Change this to the number of points you want to give
    game:GetService("PointsService"):AwardPoints(player.UserId, points)
end

-- Detect when a player clicks on the NPC's ClickDetector
clickDetector.MouseClick:Connect(function(player)
    local isStaffMember = player:IsInGroup(STAFF_GROUP_ID) -- Change this to your staff group ID
    if isStaffMember then
        handleStaffInteraction(player)
    end
end)

I hope this code helps you achieve what you were looking for. Let me know if you have any questions.

Thanks for this, however, I’m wanting to award a leaderstat as opposed as actual points.

Sure, you can use Player:LoadNumber() and Player:SaveNumber() functions to set a value to a leaderstat. Here’s an updated example that awards a leaderstat instead of points:

-- Define the NPC and the ProximityPrompt
local npc = workspace.NPC
local prompt = Instance.new("ProximityPrompt")
prompt.Parent = npc
prompt.ActionText = "Place your order"

-- Group ID for staff members
local STAFF_GROUP_ID = 123456789 -- Change this to your staff group ID

-- Define a function to handle the player's order
local function handleOrder(player)
    -- Open a dialog to collect the player's order
    local order = game:GetService("TeleportService"):TeleportPlaceAsync(ORDER_DIALOG_ID, player)

    -- Store the order in a datastore
    local datastore = game:GetService("DataStoreService"):GetDataStore("orders")
    datastore:SetAsync(player.UserId, order)

    -- Give the player staff points when the order is complete
    local leaderstat = "Orders" -- Change this to the name of the leaderstat you want to modify
    local value = player:GetAttribute(leaderstat) or 0
    value = value + 1 -- Increment the value
    player:SetAttribute(leaderstat, value) -- Update the leaderstat
    player:SaveNumber(leaderstat, value) -- Save the leaderstat to the player's data
end

-- Detect when a player clicks on the NPC's ProximityPrompt
prompt.Triggered:Connect(function(player)
    handleOrder(player)
end)

In this updated code, we store and retrieve a custom leaderstat value for the player using Player:GetAttribute() and Player:SetAttribute(). Then we use Player:SaveNumber() to save the value to the player’s data.

I hope this helps! Let me know if you have any questions.

Thanks! How would I add the NPC actually talking the order, and make it randomized from a list?

To make the NPC talk and give a randomized order, you can do the following:

  1. Create a list of possible orders that the NPC can give.

  2. When the staff member player interacts with the NPC, randomly select an order from the list.

  3. Create a dialog box to display the NPC’s order to the staff member player.

  4. Create a dialogue sound that plays while the NPC is giving the order.

Here’s how the code would look like:

-- Define the NPC and the ProximityPrompt
local npc = workspace.NPC
local prompt = Instance.new("ProximityPrompt")
prompt.Parent = npc
prompt.ActionText = "Take Order"

-- Define a list of possible orders
local orders = {"cheeseburger", "fries", "soda", "hot dog", "onion rings", "milkshake"}

-- Define a function to handle the staff member player's interaction with the NPC
local function handleStaffInteraction(player)
    -- Randomly select an order from the list
    local orderIndex = math.random(1, #orders)
    local npcOrder = orders[orderIndex]

    -- Create a dialog to display the NPC's order
    local dialog = Instance.new("Dialog")
    dialog.Name = "NPC Order"
    dialog.Parent = game:GetService("ReplicatedStorage")
    dialog.Initiator = npc.Head
    dialog.InstantText = "Hello! Can I take your order please?"
    local option = Instance.new("DialogOption")
    option.Name = "NPC Order"
    option.Value = npcOrder
    option.Prompt = "Here's your order:"
    option.ResponseDialog = nil
    dialog.DialogOptions = {option}
    dialog:Clone().Parent = player.PlayerGui

    -- Play a dialogue sound while the NPC is giving the order
    npc.Head.Dialogue.SoundId = "rbxassetid://123456"
    wait(1)
    npc.Head.Dialogue:Play()

    -- Store the NPC's order in a datastore
    local datastore = game:GetService("DataStoreService"):GetDataStore("orders")
    datastore:SetAsync("npc_order", npcOrder)

    -- Give the staff member player staff points when the order is complete
    local leaderstat = "Orders" -- Change this to the name of the leaderstat you want to modify
    local value = player:GetAttribute(leaderstat) or 0
    value = value + 1 -- Increment the value
    player:SetAttribute(leaderstat, value) -- Update the leaderstat
    player:SaveNumber(leaderstat, value) -- Save the leaderstat to the player's data
end

-- Detect when a player clicks on the NPC's ProximityPrompt
prompt.Triggered:Connect(function(player)
    local isStaffMember = player:IsInGroup(STAFF_GROUP_ID) -- Change this to your staff group ID
    if isStaffMember then
        handleStaffInteraction(player)
    else
        -- Display a message telling the player they must be a staff member to take orders
        print("You must be a staff member to take orders.")
    end
end)

In this updated code, the orders table holds a list of possible orders that the NPC can give. When the staff member player clicks on the ProximityPrompt, the script selects a random order from the orders table and displays it in a dialog box. The npc.Head.Dialogue object is a Sound object that plays a dialogue sound effect.

I hope this helps you! Let me know if you have any questions.

Thanks so much, I’m really excited to try this out! How would I add a NPC walking in effect, and the cashier giving the NPC a order, and if it’s wrong they don’t get the points (using tool names), this system would be based on Proximity Prompts.

To add an NPC walking effect, you can use TweenService to change the position of the NPC. Here’s an example that makes the NPC walk towards the cashier:

local npc = workspace.NPC
local cashier = workspace.Cashier

-- Set the starting and ending positions of the NPC and the time it takes to get there
local startPos = npc.PrimaryPart.Position
local endPos = cashier.PrimaryPart.Position - cashier.PrimaryPart.CFrame.UpVector * 3
local time = 2 -- in seconds

-- Use TweenService to animate the NPC walking towards the cashier
local info = TweenInfo.new(time, Enum.EasingStyle.Linear)
local tween = game:GetService("TweenService"):Create(npc.PrimaryPart, info, {Position = endPos})
tween:Play()

To handle the cashier giving the NPC an order and giving the player staff points based on the correctness of the order, you can modify the handleStaffInteraction function I provided earlier. Here’s how it can be done:

local function handleStaffInteraction(player)
    -- Make the NPC walk towards the cashier
    local npc = workspace.NPC
    local cashier = workspace.Cashier
    local endPos = cashier.PrimaryPart.Position - cashier.PrimaryPart.CFrame.UpVector * 3
    local time = 2 -- in seconds
    local info = TweenInfo.new(time, Enum.EasingStyle.Linear)
    local tween = game:GetService("TweenService"):Create(npc.PrimaryPart, info, {Position = endPos})
    tween:Play()

    -- Wait until the NPC reaches the cashier and interact with the ProximityPrompt
    wait(time)
    local prox = cashier.ProximityPrompt
    prox.Triggered:Wait()

    -- Get the order from the tool the player is holding
    local order = nil
    local tool = player.Character:FindFirstChildWhichIsA("Tool")
    if tool then
        order = tool.Name
    end

    -- Check if the order is correct and give rewards accordingly
    local correctOrder = "cheeseburger" -- change this to the correct tool name
    if order == correctOrder then
        -- Player got the correct order, give staff points
        local leaderstat = "Orders" -- Change this to the name of the leaderstat you want to modify
        local value = player:GetAttribute(leaderstat) or 0
        value = value + 1 -- Increment the value
        player:SetAttribute(leaderstat, value) -- Update the leaderstat
        player:SaveNumber(leaderstat, value) -- Save the leaderstat to the player's data
        print("Staff member "..tostring(player.Name).." got the order correct and was awarded staff points.")
    else
        -- Player got the wrong order, don't give staff points
        print("Staff member "..tostring(player.Name).." got the order wrong and was not awarded staff points.")
    end

    -- Make the NPC walk back to its original position
    info = TweenInfo.new(time, Enum.EasingStyle.Linear)
    tween = game:GetService("TweenService"):Create(npc.PrimaryPart, info, {Position = startPos})
    tween:Play()
end

In this updated code, when a staff member player interacts with the NPC, the handleStaffInteraction function moves the NPC towards the cashier using TweenService. Once the NPC reaches the cashier, the player is expected to give the correct tool name. If the order is correct, staff points are awarded to the player based on their leaderstat value. Otherwise, no staff points are awarded. After the NPC has interacted with the cashier and the player is done checking the order, the NPC walks back to its original position.

I hope this helps! Let me know if you have any questions.

2 Likes

@CookieTechAi

Can you put all of the above into one message? (A summary)

Sure, here’s a summary of the changes you can make to the code I provided earlier:

  1. To add a walking effect for the NPC, you can use TweenService to animate the position of the NPC from its start position to its end position. Here’s an example:
local npc = workspace.NPC
local cashier = workspace.Cashier
local startPos = npc.PrimaryPart.Position
local endPos = cashier.PrimaryPart.Position - cashier.PrimaryPart.CFrame.UpVector * 3
local time = 2 -- in seconds
local info = TweenInfo.new(time, Enum.EasingStyle.Linear)
local tween = game:GetService("TweenService"):Create(npc.PrimaryPart, info, {Position = endPos})
tween:Play()
  1. To handle the cashier giving the NPC an order and giving the player staff points based on the correctness of the order, you can modify the handleStaffInteraction function I provided earlier. Here’s a summary of the changes:
  • Make the NPC walk towards the cashier using TweenService.

  • Wait until the NPC reaches the cashier and the player interacts with the ProximityPrompt.

  • Get the order from the tool the player is holding.

  • Check if the order is correct and give rewards accordingly.

  • Make the NPC walk back to its original position using TweenService.

Here’s the modified function:

local function handleStaffInteraction(player)
    -- Make the NPC walk towards the cashier using TweenService
    local npc = workspace.NPC
    local cashier = workspace.Cashier
    local startPos = npc.PrimaryPart.Position
    local endPos = cashier.PrimaryPart.Position - cashier.PrimaryPart.CFrame.UpVector * 3
    local time = 2 -- in seconds
    local info = TweenInfo.new(time, Enum.EasingStyle.Linear)
    local tween = game:GetService("TweenService"):Create(npc.PrimaryPart, info, {Position = endPos})
    tween:Play()

    -- Wait until the NPC reaches the cashier and the player interacts with the ProximityPrompt
    wait(time)
    local prox = cashier.ProximityPrompt
    prox.Triggered:Wait()

    -- Get the order from the tool the player is holding
    local order = nil
    local tool = player.Character:FindFirstChildWhichIsA("Tool")
    if tool then
        order = tool.Name
    end

    -- Check if the order is correct and give rewards accordingly
    local correctOrder = "cheeseburger" -- change this to the correct tool name
    if order == correctOrder then
        -- Player got the correct order, give staff points
        local leaderstat = "Orders" -- Change this to the name of the leaderstat you want to modify
        local value = player:GetAttribute(leaderstat) or 0
        value = value + 1 -- Increment the value
        player:SetAttribute(leaderstat, value) -- Update the leaderstat
        player:SaveNumber(leaderstat, value) -- Save the leaderstat to the player's data
        print("Staff member "..tostring(player.Name).." got the order correct and was awarded staff points.")
    else
        -- Player got the wrong order, don't give staff points
        print("Staff member "..tostring(player.Name).." got the order wrong and was not awarded staff points.")
    end

    -- Make the NPC walk back to its original position using TweenService
    info = TweenInfo.new(time, Enum.EasingStyle.Linear)
    tween = game:GetService("TweenService"):Create(npc.PrimaryPart, info, {Position = startPos})
    tween:Play()
end

I hope this summary helps! Let me know if you have any questions.

This topic was automatically closed after 7 days. New replies are no longer allowed.