Trouble CFraming players

Hi!

I want to make a Queuesystem that takes the players to there object in the same map.

I can’t figure out how to teleport the second player to his part.

I have looked at the devforum but the only thing i find is TS.

If i set the “maxplayers” of my script to 1 and try to queue they spawn correctly.
but if i set “maxplayers” to 2. It teleports only the last 1 touching.

What i want to know is if there is a way to get the character out of my table. (Every player who queue get in there) Or do i need to approach it from another angle?

local QueueGui = workspace.Model.Knopje.QueueGui
local Queue = {}
local MaxQueue = 2
local gameTele1 = workspace.Start.StartP1
local gameTele2 = workspace.Start.StartP2
local playerInQueue = workspace.playerInQueue
local ProximityPromptService = game:GetService("ProximityPromptService")
local proximityPrompt = script.Parent
local setStart = workspace.setStart

local function updateQueueGui()
	QueueGui.Queue.Text = "Queue: " ..#Queue.. "/2"
end

local function onPromptTriggered(promptObject, player)	

end	

proximityPrompt.Triggered:Connect(function(player)

	local player = game.Players:FindFirstChild(player.Name)
	local alreadyExists = false

	for i=1,#Queue do
		if Queue[i] == player.Name then
			alreadyExists = true
		end
	end

	if alreadyExists == false then


		if playerInQueue.Value < MaxQueue then
			table.insert(Queue, player.Name)
			playerInQueue.Value = playerInQueue.Value + 1
			updateQueueGui()

			print("looking for second player")
		end

		if playerInQueue.Value == MaxQueue then
			if gameTele1.Free.Value == true then
				player.Character.HumanoidRootPart.CFrame = gameTele1.CFrame
				gameTele1.Free.Value = false
		
		elseif  gameTele1.Free.Value == false and gameTele2.Free.Value == true then
			player.Character.HumanoidRootPart.CFrame = gameTele2.CFrame
			gameTele2.Free.Value = false
				
				
			end
			wait(5)
			setStart.CanCollide = false
				print("Game Starting")
		end


	end
	end)

Try moving the Torso instead HRP.

naah, i dont think that works. Everything is connected via constraints to the HRP. Moving the Torso will not affect Other parts, like the head or a leg.

EDIT: PivotTo works better in models

Player.Character:SetPrimaryPartCFrame("CFrame goes here")

https://developer.roblox.com/en-us/api-reference/function/Model/SetPrimaryPartCFrame

Im in the bus. Ill make an version, that works, soon

1 Like

Now im Home :coefficients: - But Here:

local QueueGui = workspace.Model.Knopje.QueueGui
local Queue = {}
local MaxQueue = 2
local gameTele1 = workspace.Start.StartP1
local gameTele2 = workspace.Start.StartP2
local playerInQueue = workspace.playerInQueue
local ProximityPromptService = game:GetService("ProximityPromptService")
local proximityPrompt = script.Parent
local setStart = workspace.setStart

local function updateQueueGui()
	QueueGui.Queue.Text = "Queue: " ..#Queue.. "/" .. MaxQueue
end

local function onPromptTriggered(promptObject, player)	

end	

proximityPrompt.Triggered:Connect(function(player)

	local player = game.Players:FindFirstChild(player.Name)
	local alreadyExists = false

	for i=1,#Queue do
		if Queue[i] == player.Name then
			alreadyExists = true
		end
	end

	if alreadyExists == false then


		if playerInQueue.Value < MaxQueue then
			table.insert(Queue, player.Name)
			playerInQueue.Value = playerInQueue.Value + 1
			updateQueueGui()

			print("looking for second player")
		end

		if playerInQueue.Value == MaxQueue then
			if gameTele1.Free.Value == true then
				player.Character.HumanoidRootPart.CFrame = gameTele1.CFrame
				gameTele1.Free.Value = false
			else if gameTele2.Free.Value == true then
					player.Character.HumanoidRootPart.CFrame = gameTele2.CFrame
					gameTele2.Free.Value = false
				end
			end
			wait(5)
			setStart.CanCollide = false
			print("Game Starting")
		end
	end
end)

Maybe This Works? Please Tell Me :slight_smile:

When you use SetPrimaryPartCFrame, you can receive floating point errors that disposition the parts in the assembly you’re moving over time. You should use PivotTo in this case.

1 Like

Queue system

You can create a relatively simple queue system using a little bit of OOP (object-oriented programming) for structure reasons.

-- Variables
local startP1 = workspace.Start.StartP1
local startP2 = workspace.Start.StartP2

local queue = {Characters = {}}

-- Functions
local function GetHeight(character)
    local humanoid = character.Humanoid
    local root = character.HumanoidRootPart
    local hipHeight = humanoid.HipHeight
    
    if humanoid.RigType == Enum.RigType.R15 then
        return (0.5 * root.Size.Y) + hipHeight
    else
        local leftLeg = character.LeftLeg
        return leftLeg.Size.Y + (0.5 * root.Size.Y) + hipHeight
    end
end

local function Teleport(character, position)
    local height = GetHipHeight(character)
    
    character.HumanoidRootPart.CFrame = CFrame.new(position + Vector3.new(0, height, 0))
end

-- Methods
function queue:Add(character)
    -- Check if exists
    if table.find(self.Characters, character) then
        return
    end
    
    -- Insert to table
    table.insert(self.Characters, character)
    
    -- If enough characters in queue, handle
    if #self.Characters == self.Limit then
        self:Handle()
    else
        print("Waiting for more players")
    end
end

function queue:Remove(character)
    local index = table.find(self.Characters, character)
    if index then
        table.remove(self.Characters, index)
    end
end

function queue:Handle()
    local character1, character2 = self.Characters[1], self.Characters[2]
    
    -- Verify characters
    if not character1.Parent then
        self:Remove(character1)
        return
    elseif not character2.Parent then
        self:Remove(character2)
        return
    end
    
    -- Clear queue
    self:Remove(character1)
    self:Remove(character2)
    
    -- Teleport characters
    Teleport(character1, startP1)
    Teleport(character2, startP2)

    print("Game starting")
end

To use this, you simply call the method :Add(<character>) in the proximity prompt function.

Teleporting the character

Make sure to account for the character’s height when you set the root’s CFrame to ensure that the character doesn’t get moved inside the ground.

Roblox shows examples here on how to go about calculating the absolute hip height (distance between the feet and the root) which you then would use to offset the CFrame when you’re setting it.

You can apply the offset like so:

character.HumanoidRootPart.CFrame = CFrame.new(part.Position + Vector3.new(0, height, 0))

They should set the root’s CFrame in this case actually, since like @Ratzifutzi mentioned, everything is connected to the root.

3 Likes

Well, that helped me too, thank you for the knowledge!

1 Like

Nope. It still does the same as before.
Thanks for looking into it.

Could me meet up Discord? I really want to help you.

Thanks for offering help. I don’t have much time to be on Discord this week.
Still trying… It’s like the script forgets the first person who touched… and only teleports the last one.

make sure you enable the second player’s archivable by getting the player’s character like

for _,v in pairs(game.Players:GetChildren(secondPlayer)) do
         v.Character.Archivable = true
         v.Character.PrimaryPart.CFrame = part.CFrame
end

this should allow you to teleport the other player to the part
just make sure you make the part.CFrame the actual name of the part you’re teleporting the second player into.

--Variables

local QueueGui = workspace.Model.Knopje.QueueGui
local Queue = {}
local MaxQueue = 1
local gameTele1 = workspace.Start.StartP1
local gameTele2 = workspace.Start.StartP2
local playerInQueue = workspace.playerInQueue
local ProximityPromptService = game:GetService("ProximityPromptService")
local proximityPrompt = workspace.Model.Knopje.ProximityPrompt
local setStart = workspace.setStart


--Functions

local function updateQueueGui()
	QueueGui.Queue.Text = "Queue: " ..#Queue.. "/" .. MaxQueue
end

local function onPromptTriggered(promptObject, player)	

end	

local function Teleport(player, position)
	player.Archivable = true
	player.Character.primaryPart.CFrame = position.CFrame
end

proximityPrompt.Triggered:Connect(function(player)

	local player = game.Players:FindFirstChild(player.Name)
	local alreadyExists = false

	for i=1,#Queue do
		if Queue[i] == player.Name then
			alreadyExists = true
		end
	end

	if alreadyExists == false then


		if playerInQueue.Value < MaxQueue then
			table.insert(Queue, player.Name)
			playerInQueue.Value = playerInQueue.Value + 1
			updateQueueGui()

			print("looking for second player")
		end

		if playerInQueue.Value == MaxQueue then
			local Character = player.Character
			
			if gameTele1.Free.Value == true then
				print(Character)
				Teleport(player, gameTele1)
				gameTele1.Free.Value = false
				
			else if gameTele1.Free.Value == false and gameTele2.Free.Value == true then
				Teleport(player, gameTele2)
				gameTele2.Free.Value = false
				end
			end
			wait(5)
			setStart.CanCollide = false
			setStart.Transparency = 1
			print("Game Starting")
		end
	end
end)

Doesn’t seem to do the trick.

try changing the player.Archivable to player.Character.Archivable

Already tried it. nothing changed.

wait does your script have a way to get the “second player”'s name?

No thats the part i try to figure out .
I tried getting the second player out of the table but without succes.

ohhh i thought u did alright… gonna do some adjustments unless others have already solved it

1 Like

I think what might be going on is that you’re teleporting the last player who activated the proximity prompt. When the proximity prompt is activated, that player is added into the queue it looks like, and then when the max queue is reached, you use your teleport function on the player variable. All that player variable is, is the last person to activate the proximity prompt. To fix this, when calling the teleport function from your proximity event, put that function inside a for loop, and loop through the the queue table:

for i, v in pairs(Queue) do
         if gameTele1.Free.Value == true then
		print(Character)
		Teleport(v, gameTele1)
             gameTele1.Free.Value = false
     end
end

(Sorry I’m on my phone so the code formatting is really messed up)