I have a script that creates a SurfaceGui with N/A number of frames vertically and horizontally, how do I get their world position?
I almost got it by this code:
local Part = self.surface
local Side = self.gui.Face
local TopLeft = CFrame.new()
if Side == Enum.NormalId.Front then
TopLeft = Part.CFrame * CFrame.new(Part.Size.X/2,Part.Size.Y/2,-Part.Size.Z/2)
elseif Side == Enum.NormalId.Back then
TopLeft = Part.CFrame * CFrame.new(-Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2)
elseif Side == Enum.NormalId.Left then
TopLeft = Part.CFrame * CFrame.new(-Part.Size.X/2,Part.Size.Y/2,-Part.Size.Z/2)
elseif Side == Enum.NormalId.Right then
TopLeft = Part.CFrame * CFrame.new(Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2)
end
local TopLeftPosition = TopLeft.Position
TopLeftPosition = Vector3.new(TopLeftPosition.x / 2, TopLeftPosition.y / 2, TopLeftPosition.z / 2)
for x=0, self.resolution.x-1 do
for y=0, self.resolution.y-1 do
if self.pixels[tostring(x) + tostring(y)] then
local world_vector = self.pixels[tostring(x) + tostring(y)].world_vector
local frame = self.pixels[tostring(x) + tostring(y)][tostring(x) + tostring(y)]
world_vector.Value = TopLeftPosition + Vector3.new((self.surface.size.x * x)/2, (self.surface.size.y * y)/2, TopLeftPosition.z)
local p = Instance.new("Part", workspace)
p.Anchored = true
p.Size = Vector3.new(0.1, 0.1, 0.1)
p.Position = world_vector.Value
end
end
end
but it still make it wrong
Ah my bad I read SurfaceGui as ScreenGui somehow.
local Part = self.surface
local Side = self.gui.Face
local TopLeft = CFrame.new()
local width = 0
local height = 0
-- Use CFrame.Angles to orient the TopLeft CFrame such that TopLeft.rightVector is in the x direction of the surface gui and -TopLeft.upVector is in the y direction of the surface gui
if Side == Enum.NormalId.Front then
TopLeft = Part.CFrame * CFrame.new(Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2) * CFrame.Angles(0, math.rad(180), 0)
width = Part.Size.X
height = Part.Size.Y
elseif Side == Enum.NormalId.Back then
TopLeft = Part.CFrame * CFrame.new(-Part.Size.X/2,Part.Size.Y/2,-Part.Size.Z/2)
width = Part.Size.X
height = Part.Size.Y
elseif Side == Enum.NormalId.Left then
TopLeft = Part.CFrame * CFrame.new(-Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2) * CFrame.Angles(0, 0, math.rad(-90) )
width = Part.Size.Z
height = Part.Size.Y
elseif Side == Enum.NormalId.Right then
TopLeft = Part.CFrame * CFrame.new(Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2) * CFrame.Angles(0, math.rad(90), 0)
width = Part.Size.Z
height = Part.Size.Y
end
for x=0, self.resolution.x-1 do
for y=0, self.resolution.y-1 do
if self.pixels[tostring(x) + tostring(y)] then
local world_vector = self.pixels[tostring(x) + tostring(y)].world_vector
local frame = self.pixels[tostring(x) + tostring(y)][tostring(x) + tostring(y)]
-- Use the TopLeft CFrame to get the world position
world_vector.Value = TopLeft.Position + ( TopLeft.RightVector * x / self.resolution.x * width - TopLeft.UpVector * y / self.resolution.y * height)
local p = Instance.new("Part", workspace)
p.Anchored = true
p.Size = Vector3.new(0.1, 0.1, 0.1)
p.Position = world_vector.Value
end
end
end
This works but it’s on the wrong side when it should be on NormalId Front it’s on Back
Like this: Frames on front, and the points on back
works perfectly, swapped back and front
Ah I must have got the Enums mixed up but it seems like you’ve fixed it now
yep, thanks, you just helped me alot < 3
Im sorry but can you help me with coe again? I make it to use pixel by pixel and now i using
function pixel:update(surface, face, resolution)
local Part = surface
local Side = face
local TopLeft = CFrame.new()
local width = 0
local height = 0
-- Use CFrame.Angles to orient the TopLeft CFrame such that TopLeft.rightVector is in the x direction of the surface gui and -TopLeft.upVector is in the y direction of the surface gui
if Side == Enum.NormalId.Front then
TopLeft = Part.CFrame * CFrame.new(-Part.Size.X/2,Part.Size.Y/2,-Part.Size.Z/2)
width = Part.Size.X
height = Part.Size.Y
elseif Side == Enum.NormalId.Back then
TopLeft = Part.CFrame * CFrame.new(Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2) * CFrame.Angles(0, math.rad(180), 0)
width = Part.Size.X
height = Part.Size.Y
elseif Side == Enum.NormalId.Left then
TopLeft = Part.CFrame * CFrame.new(-Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2) * CFrame.Angles(0, 0, math.rad(-90) )
width = Part.Size.Z
height = Part.Size.Y
elseif Side == Enum.NormalId.Right then
TopLeft = Part.CFrame * CFrame.new(Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2) * CFrame.Angles(0, math.rad(90), 0)
width = Part.Size.Z
height = Part.Size.Y
end
local position = self.instance.AbsolutePosition
print(position)
self.world_position = TopLeft.Position + ( TopLeft.RightVector * position.x / resolution.x * width - TopLeft.UpVector * position.y / resolution.y * height)
local p = Instance.new("Part", workspace)
p.Anchored = true
p.Size = Vector3.new(0.1, 0.1, 0.1)
p.Position = self.world_position
end
but that doesn’t work, pls help if you can
What is wrong with it/ what issue are you having?
It arranges the vectors incorrectly, most likely this is due to the lack of a for loop, because I am addressing the pixel directly
Is this something like a frame directly parented to the surface gui then?
yep, thats it, i need three characters
to reply
I think the rearrangement of front to back hasn’t been done properly maybe then. I reckon it should be this
if Side == Enum.NormalId.Front then
TopLeft = Part.CFrame * CFrame.new(Part.Size.X/2,Part.Size.Y/2,-Part.Size.Z/2) * CFrame.Angles(0, math.rad(180), 0)
width = Part.Size.X
height = Part.Size.Y
elseif Side == Enum.NormalId.Back then
TopLeft = Part.CFrame * CFrame.new(-Part.Size.X/2,Part.Size.Y/2,Part.Size.Z/2)
width = Part.Size.X
height = Part.Size.Y
that doesn’t helped, yet, it still very big distance…
What are you passing in for the resolution?
literally nothing because the method is in pixel
You need to pass in the resolution (in pixels) of the surface gui in order for it to work.