Teleporting to the wrong plate | CollectionService

Hi again! So, for context, I am using CollectionService to group these plates, since they all share the same code. If the person falls off the plate, it will teleport above it.

However, due to how CollectionService works, it teleports to the last plate that has been found by it. This is an issue because it can either teleport back or forward the user, alternating their progress. Are there any suggestions for this? (Should I make a new post for this?)

I have 2 scripts that communicate with each other via a BindableEvent:

Plates Script

local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local FallEvent = game:GetService("ReplicatedStorage").Events.BindableEvents.UserFall

local debounce = false

for _, plate in CollectionService:GetTagged("Plate") do
	
	FallEvent.Event:Connect(function(ACTION)
		
		if ACTION == "GET_PLATE" then
			if debounce == false and plate:GetAttribute("debounce") == true then
				debounce = true
				print("Fired!")
				FallEvent:Fire("RECEIVE_PLATE", plate)
				task.wait(1)
				debounce = false
			end
		end
	end)
	
	plate.Touched:Connect(function(hit)
		if plate:GetAttribute("debounce") ~= false then return end
		
		local pitchList = {0.8, 1, 1.2, 1.4, 1.6, 1.8, 2}
		local color = Color3.fromRGB(math.random(120, 200),math.random(120, 200),math.random(120, 200))
		
		if hit.Parent.Humanoid then
			local player = Players:GetPlayerFromCharacter(hit.Parent)
			player:SetAttribute("lastPlatePos", plate.Position)
			plate:SetAttribute("debounce", true)
			
			-- Play Note
			local printChoice = pitchList[math.random(1,7)]
			plate.Note.Pitcher.Octave = printChoice
			plate.Note:Play()
			
			-- Clone
			local plateClone = plate:Clone()
			plateClone.CanCollide = false
			plateClone.CanTouch = false
			plateClone.Transparency = 0.5
			plateClone.Material = Enum.Material.Neon
			plateClone.Color = color
			plateClone.Parent = workspace
			plateClone.Note:Destroy()
			
			-- Tweens
			local TweenOne = TweenService:Create(plate, TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {Color = color, Position = Vector3.new(plate.Position.X, plate.Position.Y - 2, plate.Position.Z)})
			TweenOne:Play()
			
			local TweenTwo = TweenService:Create(plate, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, true), {Size = Vector3.new(plate.Size.X - 2,plate.Size.Y - 0.5,plate.Size.Z - 2)})
			TweenTwo:Play()
			
			local TweenThree = TweenService:Create(plateClone, TweenInfo.new(2, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {Transparency = 1, Size = Vector3.new(plate.Size.X + 12 ,plate.Size.Y,plate.Size.Z + 12)})
			TweenThree:Play()
			
			task.defer(function()
				TweenThree.Completed:Wait()
				plateClone:Destroy()
			end)
			
			-- Properties
			plate.Material = Enum.Material.Neon
		end
	end)
end

Fall Script

local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local FallEvent = game:GetService("ReplicatedStorage").Events.BindableEvents.UserFall

local debounce = false

for _, fallBreaker in CollectionService:GetTagged("FallBreaker") do
	fallBreaker.Touched:Connect(function(hit)
		local Success, Error = pcall(function()
			if hit.Parent.Humanoid then

				FallEvent:Fire("GET_PLATE")

				local player = Players:GetPlayerFromCharacter(hit.Parent)
				local HRP = hit.Parent.HumanoidRootPart
				HRP.Position = Vector3.new(player:GetAttribute("lastPlatePos").X, player:GetAttribute("lastPlatePos").Y + 1000, player:GetAttribute("lastPlatePos").Z)

				FallEvent.Event:Connect(function(ACTION, PLATE)
					if ACTION ~= "RECEIVE_PLATE" then return end
					
					PLATE.AlignPosition.Enabled = true
					PLATE.AlignPosition.Attachment1 = HRP.RootAttachment
					PLATE.MoveTo.CFrame = CFrame.new(Vector3.new(0,1000,0))
					
					if debounce == false then
						debounce = true
						local Tween = TweenService:Create(PLATE.MoveTo, TweenInfo.new(4, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), {CFrame = CFrame.new(Vector3.new(0,10,0))})
						Tween:Play()
						Tween.Completed:Wait()
						PLATE.AlignPosition.Enabled = false
						debounce = false
					end
				end)
			end
		end)

		if not Success then
			warn(Error)
		end
	end)
end

Here is the current situation in action:
Watch Teleporting to the wrong plate | Streamable

I thought about giving each plate a Unique ID (A number attribute), however I thought there may be a better solution to this. Thanks!

2 Likes

i got a logical solution :

  1. give parts random ID on touch or on spawn
  2. record player’s last touched part ID
  3. search ID on fall
  4. teleport from there
1 Like

ohhh i didn’t think of that for unique ids! thanks, I’ll see if that works! :slight_smile:

1 Like

I meant like
When spawning blocks or stuff
you make it check
if ID exists
give new ID as a NumberValue under it
or when touched, etc.

I never used UNIQUE IDs of parts
i feel too lazy
better make my own NumberValue under as Attribute or as Value under part

1 Like

by UniqueID i mean custom-make it using attributes, im currently messing with it seeing what I can do :]

1 Like

The UID idea worked! Now I just need to figure out how to optimize it (and prevent it from spamming the event), thank you for the help!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.