Making a collectable object reappear in a random but specified location

In my group game, we are making a paintball matchup between a few of the group members. Instead of using flags, I am trying to create a new objective where players move around the other side to collect subspace shards.
Each collectable is worth 10 points. When the player collects one, they gain the 10 points and the object, which is a meshpart, should respawn somewhere else on the other teams side.
Each team can only gain points by collecting their color. If the opposing team collects a shard of the opposite color, the part is also collected but they lose 1 point. In both scripts, the part is destroyed in the same way.


Here, you can see the heirarchy of the parts. Currently, collecting the parts works for both sides. Here is the script we are using for that:

local shard = script.Parent
local points = 10

shard.Touched:Connect(function(hit)
	local character = hit.Parent
	local player = game.Players:GetPlayerFromCharacter(character)
	local team = player and player.Team

	if team and team.Name == "Red" then
		-- Only members of the Red team can collect the redshard
		player.leaderstats.Points.Value = player.leaderstats.Points.Value + points
		shard:Destroy()
	end
end)

The issue is that I cannot figure out how to get the parts to respawn properly. I have several parts placed around called “Redpad” which are 1x1 invisible parts with no collisions on the ground. I want the “redshard” meshpart to appear 0.5 studs above “Redpad” but they just appear in random places.
Here is the code i am using for that:

-- respawn
local redshard = game.Workspace:FindFirstChild("redshard") -- Assuming the "redshard" is in the Workspace
local redpad = game.Workspace:FindFirstChild("Redpad") -- Assuming the "Redpad" is in the Workspace

-- Function to respawn the "redshard" above the "Redpad"
local function respawnRedshard()
	if redshard and redpad then
		local spawnPosition = redpad.Position + Vector3.new(0, 0.5, 0)
		redshard.Position = spawnPosition
		redshard:MakeJoints()
		redshard.Parent = game.Workspace
	end
end

-- Function to handle the "redshard" being touched by a player
local function onTouched(hit)
	local character = hit.Parent
	if character and character:FindFirstChild("Humanoid") then
		if redshard then
			redshard:Destroy() -- destroy the "redshard" when touched
			respawnRedshard() -- respawn the "redshard" at a random location
		end
	end
end

-- Connect the "onTouched" function to the "Touched" event of the "redshard"
if redshard then
	redshard.Touched:Connect(onTouched)
end


This script doesnt work well, and I’ve tried a lot of solutions. Even the new AI (which i tried for the last script) wasn’t very helpful. (I also need the respawns to be serversided, and I have not been able to test if it is with this particular script yet) Any help at all would be appreciated

1 Like

Parts may be positioned at seemingly random parts, but it may be because when you are indexing the parts in workspace, it picks the first “RedPad” object.
If the script is inside the RedPad object, you can get it just by using Script.Parent. I would recommend a central script that handles all of the respawn locations. You can get every part under a unique tag using CollectionService and loop through them with the code which handles touched events. That way, you only need one script to handle every RedPad.
The code might look like this:

local CS = game:GetService(“CollectionService”)

local redPoints = 0

local credshards = {}

wait(3) —wait for all parts to load
local RedShard = game.ServerStorage.RedShard

local function spawnShard(spawner: Part)
    local shard = RedShard:Clone()
    shard.Parent = spawner
    shard.Position = spawner.Position + Vector3.new(0,0.5,0)
return shard
end

local RedShardSpawners = CS:GetTagged(“RedShardSpawner”)
—Gets all objects with the tag “RedShardSpawner”

for Index, Part in RedShardSpawners do
    local shard = spawnShard(Part)
    shard.Touched:Connect(function(otherPart)
        if game.Players[otherPart.Parent.Name] then
            shard.CanTouch = false
            table.insert(credshards, shard)
            redPoints = #credshards *10
        end
    end)
end
2 Likes

Thanks for the idea, that makes a lot of sense! I have edited the script to match the cases of my parts. After playing around with it for a few minutes, Im not too sure where I should place this new script. Does it go in the ServerStorage by itself, or does the whole RedShard object go with it?

1 Like

The script should go in ServerScriptService, and a reference should be made to the shard in ServerStorage