Problem with Ui

Im trying to make a small icon indicator for a 3D minimap however the problem is when I convert the 3D coords from the viewportframe into 2D cords for the screen/Ui the positions seem to be wrong so obviously Im doing something wrong. From the clip you can see position the small little grey icons have are wrong they don’t follow the objects in the viewportframe quite right and near the edges it cuts off a little early suggesting theres an error in cords im getting.

here is the code

local player = game.Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local viewportFrame = playerGui:WaitForChild("ScreenGui").Frame.ViewportFrame
local dragger = playerGui.ScreenGui.Frame.Dragger -- The frame to drag
local planetsFolder = viewportFrame:WaitForChild("Planets") -- Get the planets folder
local camera = Instance.new("Camera") -- Create a new camera

viewportFrame.CurrentCamera = camera -- Set the viewport frame's camera

-- Create ImageButtons for each planet (model or part)
local imageButtons = {}

local function createImageButton(planet)
	local imageButton = Instance.new("ImageButton")
	imageButton.Size = UDim2.new(0, 10, 0, 10) 
	imageButton.Parent = playerGui.ScreenGui.Frame 
	imageButton.Visible = true 
	imageButtons[planet.Name] = imageButton
end

-- Iterate through planets and create ImageButtons
for _, planet in ipairs(planetsFolder:GetChildren()) do
	if planet:IsA("Model") or planet:IsA("Part") then
		createImageButton(planet)
	end
end

local distanceFromPlanet = 6000 -- Distance from the central object
local originalPosition = dragger.Position -- Store the original position
local dragging = false
local lastMousePosition = nil
local horizontalRotation = math.rad(90) -- Starting angle for horizontal rotation
local verticalRotation = 45 -- Starting angle for vertical rotation
local verticalSensitivity = 0.01 -- Sensitivity for vertical movement
local horizontalSensitivity = 0.01 -- Sensitivity for horizontal movement
local zoomSensitivity = 100 -- Sensitivity for zooming

-- Function to update camera position based on drag offset
local function updateCameraPosition(dragOffset)
	-- Update the rotation angles with sensitivity
	horizontalRotation = horizontalRotation - (dragOffset.X * horizontalSensitivity)
	verticalRotation = verticalRotation + (dragOffset.Y * verticalSensitivity) 

	-- Clamp vertical rotation to avoid reaching extreme angles
	verticalRotation = math.clamp(verticalRotation, -math.pi / 2 + 0.15, math.pi / 2 - 0.15) 

	-- Calculate the new camera position based on spherical coordinates
	local x = distanceFromPlanet * math.cos(verticalRotation) * math.sin(horizontalRotation)
	local y = distanceFromPlanet * math.sin(verticalRotation)
	local z = distanceFromPlanet * math.cos(verticalRotation) * math.cos(horizontalRotation)

	-- Set the camera's CFrame
	camera.CFrame = CFrame.new(Vector3.new(x, y, z) + planetsFolder.Planet1.Position, planetsFolder.Planet1.Position)
end

-- Mouse input handling using UI DragDetector
local userInputService = game:GetService("UserInputService")

dragger.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		dragging = true
		lastMousePosition = userInputService:GetMouseLocation() -- Get initial mouse position
	end
end)

dragger.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		dragging = false
		dragger.Position = originalPosition -- Reset dragger position when drag ends
	end
end)


userInputService.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseWheel then
		
		distanceFromPlanet = distanceFromPlanet - (input.Position.Z * zoomSensitivity)

		
		distanceFromPlanet = math.clamp(distanceFromPlanet, 1000, 20000) 
	end
end)

game:GetService("RunService").RenderStepped:Connect(function()
	if dragging then
		local mousePosition = userInputService:GetMouseLocation()
		local dragOffset = mousePosition - lastMousePosition
		lastMousePosition = mousePosition

		updateCameraPosition(dragOffset) 
	end

	
	updateCameraPosition(Vector2.new(0, 0))

	
	for planetName, imageButton in pairs(imageButtons) do
		local planet = planetsFolder:FindFirstChild(planetName)
		if planet and (planet:IsA("Model") or planet:IsA("Part")) then
			local positionToUse = planet:IsA("Model") and planet.PrimaryPart.Position or planet.Position
			local screenPosition, onScreen = camera:WorldToScreenPoint(positionToUse)

			
			print(planet.Name .. " screenPosition: " .. tostring(screenPosition) .. " onScreen: " .. tostring(onScreen))

			if onScreen then
				
				imageButton.Position = UDim2.new(0, screenPosition.X * 903, 0, screenPosition.Y * 648)
			else
				
				imageButton.Position = UDim2.new(1, 0, 1, 0)
			end
		end
	end
end)


updateCameraPosition(Vector2.new(0, 0))

UiAspectRatioConstraint fixed it.

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