How to teleport player to random positions of a part?

I’m trying to make something where when a player touches Part1, it teleports them to a random position/the coordinates that make up Part2.

Here we have Part1 (green) and Part2 (Red). How do you make it so that when a player touches the green part, they teleport to a random position that makes up the red part?


local CurrentLocation = script.Parent
local Destination = game.Workspace.Part2
-- (Optional), You can create local variable for each part.
local RandomX = math.random(1,15.936)
local RandomZ = math.random(1,72.985)
CurrentLocation.Touched:Connect(function(Touch)
	-- Touched function.

	if Touch.Parent:FindFirstChild("HumanoidRootPart") then
		-- Checks if the touched part parent contains 'HumanoidRootPart'
		-- and if it does then this line of code will run.
		Touch.Parent:FindFirstChild("HumanoidRootPart").CFrame = Destination.CFrame + Vector3.new(RandomX,3,RandomZ)
		-- This teleports the player to the destination.
		
	end

end)

I found this script on LuaLearning, tried to modify it, but it doesn’t do exactly what I am looking for.

Edit: In RandomX and RandomZ, the 15.936 and 72.985 are the X and Z sizes of the red part.

2 Likes

I am on mobile so I can’t do an actual script, but I can offer ideas. So, you need to use math.random between the corner X/Z positions of the red part. So the bottom right corner to the top right corner etc. This effectively allows you to get a position inside the boundaries of the red. Sorry if this is confusing.

2 Likes
local RandomX = math.random(1,15.936)
local RandomZ = math.random(1,72.985)

Could be

local RandomX = math.random(-Destintion.Size.X/2,Destintion.Size.X/2)
local RandomZ = math.random(-Destintion.Size.Y/2,Destintion.Size.Y/2)

I can’t explain exactly what I’m doing but I feel like this could help

1 Like

you need to use “math.random()” the way you will do it is to get the least position point of the part, that will be the part´s position substracted by the half of all of it sizes.

local startPosition = {part}.Position - Vector3.new({part}.Size.X / 2, {part}.Size.Y / 2, {part}.Size.Z / 2)

The end position will be the same but you sum the size divided by 2

local endPosition = {part}.Position + Vector3.new({part}.Size.X / 2, {part}.Size.Y / 2, {part}.Size.Z / 2)

then you will get the random position of the start and end position which will be:

local position = Vector3.new(math.random(startPosition.X, endPosition.X), math.random(startPosition.Y, endPosition.Y), math.random(startPosition.Z, endPosition.Z))

the variable “position” will be where you will tp the player. Oh and remember to replace all the “{part}” will the location of the part itself

The reason why we substract half of the sizes to get the corners is because a parts position is the center. If we divide the size by half we will be getting what will be the corner by summing/substracting it in the position.

local xRand = math.random(Destination.Position.X - Destination.Size.X/2, Destination.Position.X + Destination.Size.X/2)
local zRand = math.random(Destination.Position.Z - Destination.Size.Z/2, Destination.Position.Z + Destination.Size.Z/2)
local posRand = Vector3.new(xRand, Destination.Position.Y, zRand) 

plr.Character:SetPrimaryPartCFrame(CFrame.new(posRand))
2 Likes

This is the script I came up with from your solution. All it does is teleports the player to the center of the part. Do you think I did something wrong?



local CurrentLocation = script.Parent
local Destination = game.Workspace.Part2
-- (Optional), You can create local variable for each part.
local startPosition = Destination.Position - Vector3.new(Destination.Size.X / 2, Destination.Size.Y / 2, Destination.Size.Z / 2)
local endPosition = Destination.Position + Vector3.new(Destination.Size.X / 2, Destination.Size.Y / 2, Destination.Size.Z / 2)
local position = Vector3.new(math.random(startPosition.X, endPosition.X), math.random(startPosition.Y, endPosition.Y), math.random(startPosition.Z, endPosition.Z))

CurrentLocation.Touched:Connect(function(Touch)
	-- Touched function.

	if Touch.Parent:FindFirstChild("HumanoidRootPart") then
		-- Checks if the touched part parent contains 'HumanoidRootPart'
		-- and if it does then this line of code will run.
		Touch.Parent:FindFirstChild("HumanoidRootPart").CFrame = Destination.CFrame + Vector3.new(position)
		-- This teleports the player to the destination.
		
	end

end)

I recommend using what @DandyWorks made its what I attempted to do but done correctly

This is what I use (define random as a Random instance):

function RandomWithinPart(Part)
    local randomCFrame = Part.CFrame * CFrame.new(random:NextNumber(-Part.Size.X/2,Part.Size.X/2), random:NextNumber(-Part.Size.Y/2,Part.Size.Y/2), random:NextNumber(-Part.Size.Z/2,Part.Size.Z/2))
    return randomCFrame
end

This will account for rotation. If you know the dimensions of what you’re teleporting, you can account for that too as with this script, it only ensures the center of the point is inside of the part, but it can hang out by teleporting object size/2 studs.

Here’s it in action (with allowing hang out)

1 Like

Thanks everyone for the help! I ended up using this one:

local CurrentLocation = script.Parent
local Destination = game.Workspace.Part2
-- (Optional), You can create local variable for each part.

CurrentLocation.Touched:Connect(function(Touch)
	-- Touched function.

	if Touch.Parent:FindFirstChild("HumanoidRootPart") then
		-- Checks if the touched part parent contains 'HumanoidRootPart'
		-- and if it does then this line of code will run.
		Touch.Parent:FindFirstChild("HumanoidRootPart").CFrame = Destination.CFrame * CFrame.new(math.random(-Destination.Size.X/2, Destination.Size.X/2),math.random(Destination.Size.Y/2, Destination.Size.Y/2),math.random(-Destination.Size.Z/2, Destination.Size.Z/2))
		-- This teleports the player to a random position inside the part.

	end

end)
local CurrentLocation = script.Parent
local Destination = game.Workspace.Part2
-- (Optional), You can create local variable for each part.
CurrentLocation.Touched:Connect(function(Touch)
	-- Touched function.

	if Touch.Parent:FindFirstChild("HumanoidRootPart") then
		-- Checks if the touched part parent contains 'HumanoidRootPart'
		-- and if it does then this line of code will run.
        local startPosition = Destination.Position - Vector3.new(Destination.Size.X / 2, Destination.Size.Y / 2, Destination.Size.Z / 2)
        local endPosition = Destination.Position + Vector3.new(Destination.Size.X / 2, Destination.Size.Y / 2, Destination.Size.Z / 2)
        local position = Vector3.new(math.random(startPosition.X, endPosition.X), math.random(startPosition.Y, endPosition.Y), math.random(startPosition.Z, endPosition.Z))
		Touch.Parent:FindFirstChild("HumanoidRootPart").Position = position 
		-- This teleports the player to the destination.
		
	end

end)
1 Like