I’m encountering an issue with my mission system where collected items are appearing to all players, even though the mission should be specific to the player who triggered it. Here’s a brief overview of the problem:
Problem:
- When a player starts a mission and collects an item, it incorrectly appears as if other players are also collecting the same item. This results in multiple players seeing the item as collected even though only one player should be able to collect it.
- The issue seems to be related to the way items are being managed and displayed, affecting all players rather than being specific to the player who triggered the mission.
Objective:
- The mission system should ensure that items to be collected are only visible to the player who initiated the mission. When a player collects an item, it should only update that player’s progress and visibility, not other players’.
- The script needs to be updated so that it handles item collection and visibility locally for each player, preventing interference between players’ missions.
Current Script Setup:
Disabled LocalScript that gets triggered via a Dialogue where the user agrees to help:
-- LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local missionProgressEvent = ReplicatedStorage:WaitForChild("Bob_MissionProgress")
local missionCompleteEvent = ReplicatedStorage:WaitForChild("Bob_MissionComplete")
local startMissionEvent = ReplicatedStorage:WaitForChild("Bob_StartMission")
local completeValueEvent = ReplicatedStorage:WaitForChild("Bob_CompleteValues")
local prompt1 = game.Workspace.DialoguePrompts.Bobby1
local prompt2 = game.Workspace.DialoguePrompts.Bobby2
local prompt3 = game.Workspace.DialoguePrompts.Bobby3
-- Signal the server to start the mission
startMissionEvent:FireServer()
-- Get GUI elements
local missionGui = playerGui:WaitForChild("Bobby_MissionGui")
local bobbyProgress = missionGui:WaitForChild("Bobby_Progress")
local progressLabel = bobbyProgress:WaitForChild("ProgressLabel")
local missionLabel = bobbyProgress:WaitForChild("MissionLabel")
local powerCellImage = bobbyProgress:WaitForChild("PowerCellImage")
local bobbyComplete = missionGui:WaitForChild("Bobby_Complete")
local powerCellImage1 = bobbyComplete:WaitForChild("PowerCellImage1")
local completeLabel = bobbyComplete:WaitForChild("CompleteLabel")
local missionLabel1 = bobbyComplete:WaitForChild("MissionLabel1")
-- Initialize GUI elements' visibility and transparency
progressLabel.Visible = false
bobbyProgress.Visible = false
powerCellImage.Visible = false
missionLabel.Visible = false
bobbyComplete.Visible = false
powerCellImage1.Visible = false
completeLabel.Visible = false
missionLabel1.Visible = false
progressLabel.TextTransparency = 1
bobbyProgress.BackgroundTransparency = 1
powerCellImage.ImageTransparency = 1
missionLabel.TextTransparency = 1
bobbyComplete.BackgroundTransparency = 1
powerCellImage1.ImageTransparency = 1
completeLabel.TextTransparency = 1
missionLabel1.TextTransparency = 1
-- Create a TweenService instance
local TweenService = game:GetService("TweenService")
-- Progress bar elements
local progressFrame = bobbyProgress:WaitForChild("ProgressFrame")
local bar = progressFrame:WaitForChild("Bar")
bar:TweenSize(UDim2.new(0, 0, 1, 0), 'Out', 'Linear', 0.5) -- start with 0 width
bar.BackgroundTransparency = 1 -- make bar transparent
progressFrame.BackgroundTransparency = 1 -- make progress frame transparent
-- Function to update the progress bar
local function updateProgressBar(current, total)
local powerCells = current
local targetWidth = powerCells / total -- calculate new width proportionally
-- Fade in the progress frame and bar
local fadeInTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local progressFrameFadeInTween = TweenService:Create(progressFrame, fadeInTweenInfo, {BackgroundTransparency = 0})
local barFadeInTween = TweenService:Create(bar, fadeInTweenInfo, {BackgroundTransparency = 0, Size = UDim2.new(targetWidth, 0, 1, 0)})
progressFrameFadeInTween:Play()
barFadeInTween:Play()
end
-- Function to fade in progress elements
local function fadeInProgressElements(current, total)
-- Create a tween to fade in all elements simultaneously
local fadeInTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local fadeInTweens = {
TweenService:Create(progressLabel, fadeInTweenInfo, {TextTransparency = 0}),
TweenService:Create(bobbyProgress, fadeInTweenInfo, {BackgroundTransparency = 0}),
TweenService:Create(powerCellImage, fadeInTweenInfo, {ImageTransparency = 0}),
TweenService:Create(missionLabel, fadeInTweenInfo, {TextTransparency = 0}),
TweenService:Create(progressFrame, fadeInTweenInfo, {BackgroundTransparency = 0}),
TweenService:Create(bar, fadeInTweenInfo, {BackgroundTransparency = 0, Size = UDim2.new(current / total, 0, 1, 0)})
}
for _, tween in pairs(fadeInTweens) do
tween:Play()
end
progressLabel.Text = string.format("You have collected %d/%d Alien Power Cells", current, total)
progressLabel.Visible = true
bobbyProgress.Visible = true
powerCellImage.Visible = true
missionLabel.Visible = true
progressFrame.Visible = true
bar.Visible = true
print("Fading in progress elements: " .. current .. "/" .. total)
end
-- Function to fade out progress elements
local function fadeOutProgressElements(callback)
local fadeOutTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local fadeOutTweens = {
TweenService:Create(progressLabel, fadeOutTweenInfo, {TextTransparency = 1}),
TweenService:Create(bobbyProgress, fadeOutTweenInfo, {BackgroundTransparency = 1}),
TweenService:Create(powerCellImage, fadeOutTweenInfo, {ImageTransparency = 1}),
TweenService:Create(missionLabel, fadeOutTweenInfo, {TextTransparency = 1}),
TweenService:Create(progressFrame, fadeOutTweenInfo, {BackgroundTransparency = 1}),
TweenService:Create(bar, fadeOutTweenInfo, {BackgroundTransparency = 1, Size = UDim2.new(0, 0, 1, 0)})
}
local completedTweens = 0
for _, tween in pairs(fadeOutTweens) do
tween.Completed:Connect(function()
completedTweens = completedTweens + 1
if completedTweens == #fadeOutTweens then
if callback then callback() end
end
end)
tween:Play()
end
wait(0.5) -- Wait for the tween to finish
-- Hide the progress GUI elements regardless of whether current reaches total or not
progressLabel.Visible = false
bobbyProgress.Visible = false
powerCellImage.Visible = false
missionLabel.Visible = false
progressFrame.Visible = false
bar.Visible = false
print("Fading out progress elements.")
end
-- Function to display progress
local function displayProgress(current, total)
local function displayMissionComplete()
-- Your code to display a message or UI indicating mission completion
print("Mission complete!")
end
fadeInProgressElements(current, total)
wait(2) -- Show the message for 2 seconds
if current == total then
fadeOutProgressElements(displayMissionComplete)
else
fadeOutProgressElements()
end
end
-- Function to display mission completion
local function displayMissionComplete()
wait(0.5) -- Wait for the progress fade out tweens to finish
completeValueEvent:FireServer()
-- Only set visibility to false if they are currently visible
if progressLabel.Visible then
progressLabel.Visible = false
end
if bobbyProgress.Visible then
bobbyProgress.Visible = false
end
if powerCellImage.Visible then
powerCellImage.Visible = false
end
if missionLabel.Visible then
missionLabel.Visible = false
end
-- Create a tween to fade in the complete label, PowerCellImage1, Bobby_Complete, and missionLabel1
local fadeInTweenInfo = TweenInfo.new(1.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out) -- Increased duration from 1 second
local fadeInTweens = {
TweenService:Create(completeLabel, fadeInTweenInfo, {TextTransparency = 0}),
TweenService:Create(powerCellImage1, fadeInTweenInfo, {ImageTransparency = 0}),
TweenService:Create(bobbyComplete, fadeInTweenInfo, {BackgroundTransparency = 0}),
TweenService:Create(missionLabel1, fadeInTweenInfo, {TextTransparency = 0})
}
completeLabel.TextTransparency = 1
powerCellImage1.ImageTransparency = 1
bobbyComplete.BackgroundTransparency = 1
missionLabel1.TextTransparency = 1
completeLabel.Text = "You Collected All Alien Power Cells. Head back to Bobby the Hippy for a Reward!"
completeLabel.Visible = true
powerCellImage1.Visible = true
bobbyComplete.Visible = true
missionLabel1.Visible = true
for _, tween in pairs(fadeInTweens) do
tween:Play()
end
completeValueEvent:FireServer()
prompt1.ProximityPrompt.Enabled = false
prompt2.ProximityPrompt.Enabled = false
prompt3.ProximityPrompt.Enabled = true
print("Displaying mission completion message.")
wait(3) -- Show the message for 5 seconds
-- Create a tween to fade out the complete label, PowerCellImage1, Bobby_Complete, and missionLabel1
local fadeOutTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local fadeOutTweens = {
TweenService:Create(completeLabel, fadeOutTweenInfo, {TextTransparency = 1}),
TweenService:Create(powerCellImage1, fadeOutTweenInfo, {ImageTransparency = 1}),
TweenService:Create(bobbyComplete, fadeOutTweenInfo, {BackgroundTransparency = 1}),
TweenService:Create(missionLabel1, fadeOutTweenInfo, {TextTransparency = 1})
}
for _, tween in pairs(fadeOutTweens) do
tween:Play()
end
wait(0.5) -- Wait for the tween to finish
completeLabel.Visible = false
powerCellImage1.Visible = false
bobbyComplete.Visible = false
missionLabel1.Visible = false
end
-- Connect events
missionProgressEvent.OnClientEvent:Connect(displayProgress)
missionCompleteEvent.OnClientEvent:Connect(displayMissionComplete)
The ServerScript:
-- ServerScript
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local collects = game.Workspace.Collects
local prompt1 = game.Workspace.DialoguePrompts.Bobby1
local prompt2 = game.Workspace.DialoguePrompts.Bobby2
local prompt3 = game.Workspace.DialoguePrompts.Bobby3
local MISSION_PARTS_COUNT = 10
local missionParts = {}
local playerProgress = {}
local collectedParts = {}
local missionProgressEvent = ReplicatedStorage:WaitForChild("Bob_MissionProgress")
local missionCompleteEvent = ReplicatedStorage:WaitForChild("Bob_MissionComplete")
local startMissionEvent = ReplicatedStorage:WaitForChild("Bob_StartMission")
local completeValueEvent = ReplicatedStorage:WaitForChild("Bob_CompleteValues")
-- Sound IDs
local PART_COLLECTED_SOUND_ID = "rbxassetid://8864375838"
local MISSION_COMPLETE_SOUND_ID = "rbxassetid://3198076659"
-- Function to create mission parts
local function createMissionParts()
for i = 1, MISSION_PARTS_COUNT do
local part = collects["PowerCell_".. i]
part.Size = part.Size
part.Position = part.Position
part.Parent = collects
part.Transparency = 0
part.PointLight.Enabled = true
part.CanTouch = true
table.insert(missionParts, part)
print("Created part: ".. part.Name)
end
end
-- Function to handle player join
local function onPlayerJoin(player)
playerProgress[player.UserId] = 0
collectedParts[player.UserId] = {}
print("Player joined: ".. player.Name)
end
-- Function to handle player leave
local function onPlayerRemoving(player)
playerProgress[player.UserId] = nil
collectedParts[player.UserId] = nil
print("Player left: ".. player.Name)
end
-- Function to play and delete sound after it finishes
local function playAndDeleteSound(soundId, parent)
local sound = Instance.new("Sound")
sound.SoundId = soundId
sound.Parent = parent
sound:Play()
sound.Ended:Connect(function()
sound:Destroy()
end)
end
-- Function to handle part collection
local function onPartCollected(player, part)
local playerId = player.UserId
local partName = part.Name
-- Check if the collectedParts table has been initialized for this player
if not collectedParts[playerId] then
collectedParts[playerId] = {}
end
-- Check if the part has already been collected by this player
if collectedParts[playerId][partName] then
return
end
-- Mark the part as collected by this player
collectedParts[playerId][partName] = true
local currentProgress = playerProgress[playerId] or 0
local newProgress = currentProgress + 1
playerProgress[playerId] = newProgress
print(player.Name.. " collected a part. Progress: ".. newProgress.. "/".. MISSION_PARTS_COUNT)
-- Play part collected sound
playAndDeleteSound(PART_COLLECTED_SOUND_ID, player.Character)
missionProgressEvent:FireClient(player, newProgress, MISSION_PARTS_COUNT)
part:Destroy()
if newProgress == MISSION_PARTS_COUNT then
print(player.Name.. " has completed the mission!")
-- Play mission complete sound
playAndDeleteSound(MISSION_COMPLETE_SOUND_ID, player.Character)
missionCompleteEvent:FireClient(player)
end
end
-- Function to connect parts
local function connectParts()
for _, part in ipairs(missionParts) do
part.Touched:Connect(function(hit)
local character = hit.Parent
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local player = Players:GetPlayerFromCharacter(character)
if player then
onPartCollected(player, part)
end
end
end)
end
end
-- Handle mission start
startMissionEvent.OnServerEvent:Connect(function(player)
if #missionParts == 0 then
prompt1.ProximityPrompt.Enabled = false
prompt2.ProximityPrompt.Enabled = true
prompt3.ProximityPrompt.Enabled = false
createMissionParts()
connectParts()
end
end)
completeValueEvent.OnServerEvent:Connect(function(player)
player.MissionValue.Bob.Value = player.MissionValue.Bob.Value + 1
end)
Players.PlayerAdded:Connect(function(player) --Already completed
wait(1)
if player.MissionValue.Bob.Value >= 1 then
prompt1.ProximityPrompt.Enabled = false
prompt2.ProximityPrompt.Enabled = false
prompt3.ProximityPrompt.Enabled = true
end
end)
-- Connect player join and leave events
Players.PlayerAdded:Connect(onPlayerJoin)
Players.PlayerRemoving:Connect(onPlayerRemoving)
print("MissionScript loaded successfully.")
and the MissionData Store Script:
local players = game.Players
local playerData = require(game.ReplicatedStorage.MissionData)
local function SavePlayerData(player)
playerData.savePlayerData(player)
end
players.PlayerAdded:Connect(function(player)
local mission = Instance.new("Folder", player)
mission.Name = "MissionValue"
local bob = Instance.new("NumberValue", mission)
bob.Name = "Bob"
local pData = playerData.loadPlayerData(player, function(data)
if data then
for _, value in ipairs(player:GetDescendants()) do
if value:IsA("NumberValue") or value:IsA("StringValue") or value:IsA("BoolValue") then
if data[value.Name] then
value.Value = data[value.Name]
end
end
end
else
print("MissionData has an error")
end
end)
while task.wait(15) do
SavePlayerData(player)
end
end)
players.PlayerRemoving:Connect(function(player)
SavePlayerData(player)
print("MissionData has been saved.")
end)
Would appreciate any help!