I am trying to make something where an ImageButton is a top-down view of the in-game world, and it’s working as intended, at least accurately along the in-game X-Axis. Though the in-game Z-Axis seems slightly offset, I do not know why.
To be specific, the top-down map is for the player to click on and retrieve a Vector3 position relative to where the player clicked on the ImageButton.
local localPlayer = game.Players.LocalPlayer
local imageButton = script.Parent
local worldWidth = 2048
local worldHeight = 2048
--// 400x400
local imageButtonWidth = imageButton.AbsoluteSize.X
local imageButtonHeight = imageButton.AbsoluteSize.Y
local scaleX = worldWidth / imageButtonWidth
local scaleZ = worldHeight / imageButtonHeight
imageButton.MouseButton1Down:Connect(function(x, y)
local pixelPosition = Vector2.new(x - imageButton.AbsolutePosition.X - imageButtonWidth * 0.5, y - imageButton.AbsolutePosition.Y - imageButtonHeight * 0.5)
local xPos = math.floor(pixelPosition.X * scaleX + 0.5)
local zPos = math.floor(pixelPosition.Y * scaleZ + 0.5)
print(pixelPosition)
print(xPos, zPos)
localPlayer.Character.HumanoidRootPart.CFrame = CFrame.new(Vector3.new(xPos, 15, zPos))
end)
local xPos = math.floor(pixelPosition.X * scaleX + 0.5)
local zPos = math.floor(pixelPosition.Y * scaleZ + 0.5)
if pixelPosition is a positive number of pixels up to imageButtonHeight/Width, then multiplying it by scale should give you between 0.0 and worldHeight/Width. Adding 0.5 to that doesn’t seem right. I think it should be:
local xPos = math.floor((pixelPosition.X / imageButtonWidth - 0.5) * worldWidth)
That way xPos is a range centered on zero with a total width of worldWidth.
Unsure if thats whats causing the Z issue.
So this is the closest I got to a solution, producing this:
local worldWidth = 2048
local worldHeight = 2048
local imageButton = script.Parent.ImageButton
local localPlayer = game.Players.LocalPlayer
local mouse = localPlayer:GetMouse()
--// 400x400
local imageButtonWidth = imageButton.AbsoluteSize.X
local imageButtonHeight = imageButton.AbsoluteSize.Y
imageButton.MouseButton1Down:Connect(function(x, y)
y = y-36 -- removing offset of topbar
local pos = Vector2.new(x,y) - imageButton.AbsolutePosition -- gets distance from center of frame to mouse click
local scalex = math.clamp(pos.X/imageButtonWidth, 0, 1)-.5 -- simple method, as accurate
local scaley = math.clamp(math.round((pos.Y/imageButtonHeight)*100)/100, 0, 1)-.5 -- rounded to produce a more stud exact result
-- scalex and scaley basically get hte % of distance from X = 0 and Y = 0 to X = 1 and Y = 1, basically if its in the bottom right corner its X = 1, Y = 1, therefore this is the scale.
local totele = Vector3.new(worldWidth*scalex, 0, worldWidth*scaley) -- uses the worldwidth and times it by the scale
print(scalex,scaley,totele) -- prints for debug
game.Players.LocalPlayer.Character:MoveTo(totele)
end)
Tried it on different sizes and what not, it doesn’t matter what size the UI is, will still produce the same effect.
Also if clicked in the right position (due to roblox’s input being extremely inconsistent) if you click right on the exact edge of the image button, it’ll teleport you to the exact edge of the map.