Minimap Angle calculation help

I have the following script:

local Minimap = script.Parent:WaitForChild("Minimap")
local Arrow = Minimap:WaitForChild("Arrow")

local IconsFolder = game.Workspace:WaitForChild("Icons")

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

local Camera = Instance.new("Camera")
Camera.FieldOfView = 1
Camera.CameraType = Enum.CameraType.Scriptable
Camera.Parent = game.Workspace
Minimap.CurrentCamera = Camera

local Ref = script.Parent.Ref

task.wait(2)

function determineAngle(part, player)
	
	local directionToPart = (part.Position - player.Character.HumanoidRootPart.Position)

	local directionToPartXZ = Vector3.new(directionToPart.X, 0, directionToPart.Z).Unit
	
	local playerForward = player.Character.HumanoidRootPart.CFrame.LookVector
	local playerForwardXZ = Vector3.new(playerForward.X, 0, playerForward.Z).Unit


	local angle = math.deg(math.atan2(playerForwardXZ.X, playerForwardXZ.Z) - math.atan2(directionToPartXZ.X, directionToPartXZ.Z))

	angle = (angle + 360) % 360
	
	print(angle)
	
	return math.round(angle)
end

function positionUIOnEdge(parentUI, angle, ui)
	
	angle = angle % 360

	local newUI = ui


	local radians = math.rad(angle)


	local radiusX = parentUI.AbsoluteSize.X + 200 / 2
	local radiusY = parentUI.AbsoluteSize.Y + 200 / 2
	local centerX = 0.5
	local centerY = 0.5

	local offsetX = math.cos(radians) * 0.7
	local offsetY = math.sin(radians) * 0.7

	local newUIWidth = newUI.Size.X.Offset / parentUI.AbsoluteSize.X
	local newUIHeight = newUI.Size.Y.Offset / parentUI.AbsoluteSize.Y

	newUI.Position = UDim2.new(
		centerX + offsetX - (newUIWidth / 2),
		0,
		centerY + offsetY - (newUIHeight / 2),
		0
	)

	return newUI
end

	

local function isPartFromCharacter(part)
	return part:IsDescendantOf(Character)
end

for i, Object in pairs(game.Workspace:GetDescendants()) do
	if isPartFromCharacter(Object) then
		continue 
	end
	if Object:IsA("Terrain") or not Object:IsA("BasePart") then
		continue 
	end
	Object:Clone().Parent = Minimap
end

function add()
	local ViewportSize = Minimap.CurrentCamera.ViewportSize
	for i, child in pairs(IconsFolder:GetChildren()) do
		local W2VP, visible = Minimap.CurrentCamera:WorldToViewportPoint(child.Position)
		local normalizedX = W2VP.X / ViewportSize.X
		local normalizedY = W2VP.Y / ViewportSize.Y
		
		if visible then
			local iconGui = Ref:FindFirstChild(child.Name.."GUI")
			if iconGui then
				iconGui.Position = UDim2.new(normalizedX, 0, normalizedY, 0)

			else
				local TextClone = script.Parent.Parent.TextLabel:Clone()
				TextClone.Text = child.Name
				TextClone.Name = child.Name.."GUI"
				TextClone.Position = UDim2.new(normalizedX, 0, normalizedY, 0)
				TextClone.Parent = Ref
				TextClone.BackgroundTransparency = 1
			end
		else
			local iconGui = Ref:FindFirstChild(child.Name.."GUI")
			
			if iconGui then
				local angle = determineAngle(child, Player)
				positionUIOnEdge(Ref, angle, iconGui)
			else
				local TextClone = script.Parent.Parent.TextLabel:Clone()
				TextClone.Text = child.Name
				TextClone.Name = child.Name.."GUI"
				TextClone.Position = UDim2.new(normalizedX, 0, normalizedY, 0)
				TextClone.Parent = Ref
				TextClone.BackgroundTransparency = 1
			end
		end
		
	end
end

function update()

	local camCFrame = CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 10000, 0), HumanoidRootPart.Position)
	Camera.CFrame = camCFrame
	Arrow.Rotation = -HumanoidRootPart.Orientation.Y - 90
	add()
end

game:GetService("RunService"):BindToRenderStep("update", 230, update)

it is for a minimap, I have text labels indicating POI’s on the minimap, I want functionality such that if the POI is off the minimap it will display the label where the POI should be, watch the attached video for my request and issue to make sense. I know it is something to do with the determine angle function, but I do not know enough about vector math to make sense of any of it

Video

Help is appreciated

I notice in the positionUIOnEdge function you’re not utilizing these. Could this be the issue?

possibly, how would i utilize them though?

local newUIWidth = newUI.Size.X.Offset / radiusX 
local newUIHeight = newUI.Size.Y.Offset / radiusY

Modify these variables to look like this

tried that, same issue present

fixed:

local Minimap = script.Parent:WaitForChild("Minimap")
local Arrow = Minimap:WaitForChild("Arrow")

local IconsFolder = game.Workspace:WaitForChild("Icons")

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

local Camera = Instance.new("Camera")
Camera.FieldOfView = 1 
Camera.CameraType = Enum.CameraType.Scriptable
Camera.Parent = game.Workspace
Minimap.CurrentCamera = Camera

local Ref = script.Parent.Ref 

task.wait(2)


function determineAngle(part, player)
	local directionToPart = (part.Position - player.Character.HumanoidRootPart.Position)
	local directionToPartXZ = Vector3.new(directionToPart.X, 0, directionToPart.Z).Unit
	local playerForward = player.Character.HumanoidRootPart.CFrame.LookVector
	local playerForwardXZ = Vector3.new(playerForward.X, 0, playerForward.Z).Unit
	local angle = math.deg(math.atan2(playerForwardXZ.X, playerForwardXZ.Z) - math.atan2(directionToPartXZ.X, directionToPartXZ.Z))
	angle = (angle + 360) % 360
	return math.round(angle)
end



function positionUIOnEdge(parentUI, projectedNormalizedX, projectedNormalizedY, ui)

	local padding = 0

	local clampedX = math.clamp(projectedNormalizedX, padding, 1 - padding)
	local clampedY = math.clamp(projectedNormalizedY, padding, 1 - padding)

	
	local uiAbsoluteWidth = ui.AbsoluteSize.X
	local uiAbsoluteHeight = ui.AbsoluteSize.Y
	local parentAbsoluteWidth = parentUI.AbsoluteSize.X
	local parentAbsoluteHeight = parentUI.AbsoluteSize.Y


	local uiNormalizedHalfWidth = (uiAbsoluteWidth / 2) / parentAbsoluteWidth
	local uiNormalizedHalfHeight = (uiAbsoluteHeight / 2) / parentAbsoluteHeight

	
	ui.Position = UDim2.new(
		clampedX - uiNormalizedHalfWidth, 
		0,
		clampedY - uiNormalizedHalfHeight, 
		0
	)
end


local function isPartFromCharacter(part)
	return part:IsDescendantOf(Character)
end


for i, Object in pairs(game.Workspace:GetDescendants()) do
	if isPartFromCharacter(Object) then
		continue
	end
	if Object:IsA("Terrain") or not Object:IsA("BasePart") then
		continue
	end
	Object:Clone().Parent = Minimap
end


function add()
	local ViewportSize = Minimap.CurrentCamera.ViewportSize 
	for i, child in pairs(IconsFolder:GetChildren()) do
	
		local W2VP, visible = Minimap.CurrentCamera:WorldToViewportPoint(child.Position)

	
		local normalizedX = W2VP.X / ViewportSize.X
		local normalizedY = W2VP.Y / ViewportSize.Y

		local iconGui = Ref:FindFirstChild(child.Name.."GUI")


		if visible then
		
			if iconGui then
				iconGui.Position = UDim2.new(normalizedX, 0, normalizedY, 0)
			else
		
				local TextClone = script.Parent.Parent.TextLabel:Clone()
				TextClone.Text = child.Name
				TextClone.Name = child.Name.."GUI"
				TextClone.Position = UDim2.new(normalizedX, 0, normalizedY, 0)
				TextClone.Parent = Ref
				TextClone.BackgroundTransparency = 1
				iconGui = TextClone
			end
			iconGui.Visible = true 
		else
			
			if iconGui then
				
				positionUIOnEdge(Ref, normalizedX, normalizedY, iconGui)
			else
				
				local TextClone = script.Parent.Parent.TextLabel:Clone()
				TextClone.Text = child.Name
				TextClone.Name = child.Name.."GUI"
				TextClone.Parent = Ref
				TextClone.BackgroundTransparency = 1
				iconGui = TextClone
			end
			iconGui.Visible = true 
		end
	end
end


function update()
	
	local camCFrame = CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 10000, 0), HumanoidRootPart.Position)
	Camera.CFrame = camCFrame
	Arrow.Rotation = -HumanoidRootPart.Orientation.Y - 90
	add() 
end

game:GetService("RunService"):BindToRenderStep("update", 230, update)
1 Like

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