Hello, I would like to obtain random coordinates located on the surface of a part. How do I proceed ?
Exemple (not working):
local position = math.random(script.Parent.TopSurface)
Thanks to all!
Hello, I would like to obtain random coordinates located on the surface of a part. How do I proceed ?
Exemple (not working):
local position = math.random(script.Parent.TopSurface)
Thanks to all!
Start where the Part is initially located, which should always be Part.Position
. The Position is always going to be in the center of it, so we to get our Position to the surface point of the Part, which should be Position + Size.Y/2
, because the Position is in the center part, that should mean both top and bottom locations are exactly half of the Size on the Y axis, because of this The Top Portion would be Positive, while the Bottom Portion would be negative.
If I had a Part with a Y Axis size of 30, this would mean both sides are exactly 15, in which we can use this information to increment upwards or downwards as a way to reach the end point
From there we have to use the rest of the axes using the same method. Instead of moving our posiion upwards to surface, we are moving it around the length and width of it.
We could tell math.random
to use Size.X/2
as a Maximum Value, but we could also use it as a Minimum value for our opposite side.
local randomAxisX = math.random(-Size.X/2, Size.X/2)
From there we can combine them form our new position
local Position = Part.Position -- Current Position
local Size = Part.Size -- Current Size
local randomX = math.random(-Size.X/2, Size.X/2)
-- it will then choose a number based on the size on the X axis
local randomX = math.random(-Size.Z/2, Size.Z/2)
-- it will then choose a number based on the size on the X axis
local Offset = Position + Vector3.new(randomX, Size.Y/2, randomZ)
-- our new position
If you place an Object on that point, its going to be inside the object due to just being on the surface, in which you can use the same method to fix that.
If the part is rectangular (on any angle), you can use this function to get a random CFrame of a position somewhere on the top surface of a part:
local function randomOnSurface(part)
local x,y,z = part.Size.X,part.Size.Y,part.Size.Z
local xPosition = math.random(-x,x)
local zPosition = math.random(-z,z)
local middle = part.CFrame + part.CFrame.UpVector*(y/2)
local rx,ry,rz = middle:ToOrientation()
return CFrame.new(middle*Vector3.new(xPosition/2,0,zPosition/2))*CFrame.Angles(rx,ry,rz)
end
make sure to pass through the part that will act as the surface.
you could try separating it into two rectangular shapes
And if it’s a triangle? I have differents shapes
You’d probably have to do some complicated math or something to achieve this on any shape.
Another option would be to use my code but repeat it until it is on the surface.
It could be possible if you were to get a vector value of each corner of the part, put it into a table and use this code:
function getRandomPoint(vertices)
local n = #vertices
if n < 3 then return end
local point = Vector3.new(0,0,0)
local vectorWeights = {}
local total = 0
for i = 1,n do
local weight = math.random()
total+=weight
table.insert(vectorWeights,weight)
end
local fixedWeight = 1/total
for i,weight in vectorWeights do
vectorWeights[i]*=fixedWeight
end
for i,vector in vertices do
point += vector * vectorWeights[i]
end
return point
end
local vertices = {
Vector3.new(0,0,0),
Vector3.new(10,0,10),
Vector3.new(20,20,20),
Vector3.new(5,5,5)
}
local randomPoint = getRandomPoint(vertices)
This works by getting each vector value its own randomly generated weight that pulls the final position in that direction. Ultimately ending with a random spot between the positions.