UI Not Moving To Position Set In A Script

It’s pretty much in the title; whenever I try to reposition a UI instance via a script it does not seem to work.

  1. What do you want to achieve? Keep it simple and clear!

I want the UI to be positioned to a certain point.

  1. What is the issue? Include screenshots / videos if possible!

The issue is from any function that tries to reposition a UI instance:

local function ShowScoreBoard(show, direction, scoreboard)
	if show == true then
		if direction == "Right" then
			scoreboard.Position = rightPosition
		else
			scoreboard.Position = leftPosition
		end
	else
		if direction == "Right" then
			scoreboard.Position = rightUnseenPosition
		else
			scoreboard.Position = leftUnseenPosition
		end
	end
	print(scoreboard.Position)
end

(in a local script obviously)

Horrible coding aside, it should work.
But instead it returns this:

image

and looks like this:

when it should look similar to this:

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

My first and foremost steps to debugging usually is asking ChatGPT (i know, i know, cringe) but after looking through all the steps it had given me:

  • :white_check_mark: Check for UI Constraints (UIListLayout).
  • :white_check_mark: Set AnchorPoint = Vector2.new(0,0).
  • :white_check_mark: Ensure Visible = true and Size is non-zero.
  • :white_check_mark: Set .Parent before .Position.
  • :white_check_mark: Use task.wait() before printing Position.
  • :white_check_mark: Manually override Position to see if it updates.

It didn’t work.

I tried checking the forums but no one seems to be facing the same issue.

Forgot to mention that the ui is created with scripts, which might be important.

Is there any particular reason for this happening? If so, can you help me fix it?

You’re not really showing anything here that would be a fixable problem.
rightPosition? leftPosition? rightUnseenPosition? leftUnseenPosition?
To us are unknown, and what your call to ShowScoreBoard(show, direction, scoreboard)
To us is unknown…

So my answer would be how to set the Position the best way.
These numbers {0, 0},{0, 0} for Position can be used differently.
The 1st number in the set of two is the better one to use as it is a scale percentage of the screen.
This works out better in the end as it can relate to any screen, PC, mobile, tablet by using scale vs using offset as in UDim2.new(XScale, XOffset, YScale, YOffset). In your case I’m guessing
{0.01, 0},{0.05, 0} … leftPosition = UDim2.new(0.01, 0, 0.05, 0)
{0.1, 0},{0.05, 0}. … rightPosition = UDim2.new(0.1, 0, 0.05, 0)

Make the anchor point (.5, .5), and make sure the position you’re setting the UI element to is a Udim 2

Sorry about that! :grimacing:
All those 4 variables are udim2s with scaling.
Basically, show is a boolean referring to whther it should be on screen or not.
Direction just refers to where it should be placed. And ScoreBoard is a frame.

Ill try that out and see if it works. Thanks for the reply though!

Yeah, no problem
Character limit

Need to see the Gui set up., and the full script to know how to fix this. It’s going to be a matter of how you have this set up or how you called it.

Alright, just a warning for your eyes (yes its that bad)

--services
local replicatedStorage = game:GetService("ReplicatedStorage")
local plrs = game:GetService("Players")
local collectionService = game:GetService("CollectionService")

--events
local updateMinigameEvent = replicatedStorage.Events.UpdateMinigameEvent
local updateHighestScoreEvent = replicatedStorage.Events.UpdateCurrentHighestScoreEvent

--int values
local values = replicatedStorage.Values

--template frame for cloning
local scoreTemplate = script.Parent.Template

--udim positions for placing (gonna replace with tweens but not right now
local leftPosition = UDim2.new({0.121, 0},{0.036, 0})
local rightPosition = UDim2.new({0.777, 0},{0.036, 0})
local leftUnseenPosition = UDim2.new({0.121, 0},{-3, 0})
local rightUnseenPosition = UDim2.new({0.777, 0},{-3, 0})

--table of every team and player's score
local scoreTable = {
	["Blue"] = {["ScoreBoard"] = script.Parent.Blue, ["Value"] = values["Blue Team Score"]},
	["Red"] = {["ScoreBoard"] = script.Parent.Red, ["Value"] = values["Red Team Score"]}
}

--connections table
local changeConnections = {}

--table template
local plrTemplate = {["ScoreBoard"] = nil, ["Value"] = nil}

-- every scoreboad ui gets put in "left unseen position"
for i, scoreBoard in collectionService:GetTagged("ScoreBoard") do
	scoreBoard.Position = leftUnseenPosition
	scoreBoard.Visible = true
end

--function for creating a scoreboard
local function createScoreBoard(plr : Player)
	local templateClone = scoreTemplate:Clone()
	
	templateClone.Parent = script.Parent
	
	print(templateClone)

	templateClone.Name = plr.Name
	templateClone.NameLabel.Text = plr.DisplayName
	templateClone.ScoreLabel.Text = values:FindFirstChild(plr.Name .. " Score").Value
	
	
	--put it at the right if its the player, or put it at the left
	if plr == plrs.LocalPlayer then
		templateClone.Position = rightUnseenPosition
	else
		templateClone.Position = leftUnseenPosition
	end
	
	print(templateClone.Position)
	
	templateClone.Visible = true
	
	scoreTable[plr] = table.clone(plrTemplate)
	
	scoreTable[plr]["ScoreBoard"] = templateClone
	scoreTable[plr]["Value"] = values:FindFirstChild(plr.Name .. " Score")
end

--updates the scoreboard every time an intvalue related to that specific 
--player or team
local function updateScores(plr)
	local tableForPlr = scoreTable[plr]

	changeConnections[plr] = tableForPlr["Value"].Changed:Connect(function(value)
		tableForPlr["ScoreBoard"].ScoreLabel.Text = value
	end)
end


--removes scoreboards for leaving players
local function removeScoreBoard(plr)
	
	if changeConnections[plr] then
		changeConnections[plr]:Disconnect()
		changeConnections[plr] = nil
	end
	
	local board = scoreTable[plr]["ScoreBoard"]
	board:Destroy()
	scoreTable[plr] = nil
end

--places the scorebord at a position depending on parameters
local function ShowScoreBoard(show, direction, scoreboard)
	if show == true then
		if direction == "Right" then
			scoreboard.Position = rightPosition
		else
			scoreboard.Position = leftPosition
		end
	else
		if direction == "Right" then
			scoreboard.Position = rightUnseenPosition
		else
			scoreboard.Position = leftUnseenPosition
		end
	end
	print(scoreboard.Position)
end

--creates a scoreboard for the local player
createScoreBoard(game.Players.LocalPlayer)
ShowScoreBoard(false, "Right", scoreTable[plrs.LocalPlayer].ScoreBoard)

--updates local player score
task.spawn(function()
	updateScores(plrs.LocalPlayer)
end)

--updates blue team score
task.spawn(function()
	updateScores("Blue")
end)

--updates red team score
task.spawn(function()
	updateScores("Red")
end)

--makes a score board for every player joining
task.spawn(function()
	plrs.PlayerAdded:Connect(function(plr)
		createScoreBoard(plr)
		updateScores(plr)
	end)
	
destroyes their scoreboard when leaving
	plrs.PlayerRemoving:Connect(function(plr)
		changeConnections[plr]:Disconnect()
		removeScoreBoard(plr)
	end)
end)

local updateScoreConnection = nil
local shownHighestScorer = nil
local plrTeam = nil

--whenever minigames update it decides which scoreboards to use
updateMinigameEvent.OnClientEvent:Connect(function(minigame)
	
-- makes them invisible
	for i, value in collectionService:GetTagged("ScoreBoard") do
		if scoreTable[value.Name] then
			if value.Name == plrs.LocalPlayer.Name  or value.Name == plrTeam then
				ShowScoreBoard(false, "Right", scoreTable[value.Name]["ScoreBoard"])
			else
				ShowScoreBoard(false, "Left", scoreTable[value.Name]["ScoreBoard"])
			end
		end
	end
	
	plrTeam = plrs.LocalPlayer.Team.Name
	
--does ffa stuff
	if minigame == "FFA" then
		
		ShowScoreBoard(true, "Right", scoreTable[plrs.LocalPlayer]["ScoreBoard"])
		
		if updateScoreConnection then
			updateScoreConnection:Disconnect()
		end
		
		updateScoreConnection = updateHighestScoreEvent.OnClientEvent:Connect(function(highestScorer)
			if shownHighestScorer ~= highestScorer then
				ShowScoreBoard(false, "Left", scoreTable[shownHighestScorer]["ScoreBoard"])
				ShowScoreBoard(true, "Left", scoreTable[highestScorer]["ScoreBoard"])
				shownHighestScorer = highestScorer
			end
		end)
		
--does tdm stuff
	elseif minigame == "TDM" then
		
		local blueTeamBoard = script.Parent.Blue.Name
		local redTeamBoard = script.Parent.Red.Name
	
		ShowScoreBoard(true, "Right", scoreTable[plrTeam]["ScoreBoard"])
		
		if plrTeam == blueTeamBoard then
			ShowScoreBoard(true, "Left", scoreTable[redTeamBoard]["ScoreBoard"])
		else
			ShowScoreBoard(true, "Left", scoreTable[blueTeamBoard]["ScoreBoard"])
		end
		
	end
end)

Do you think there are any problems with this that could be found relating to the topic here?

I tried this out, and unfortunately it didnt work.

Hi @Turbofire270

I think problem is not the script insted, you need to set IgnoreGuiInset to true in ScreenGui if you don’t top of screen will not usable.

Edit:
Sorry I didn’t read post fully,

In script:

Gui.IgnoreGuiInset = true

In your script try:

script.Parent.IgnoreGuiInset  = true

Make sure script.Parent is a screen gui

I tried that, but it didnt work. Hmmm…
Ill read all the properties and see if i can find out why this is happening.
Thanks for your time!

1 Like

Do you really need to move the Gui when it’s not seen?

I mean, no. But even if i try to move the gui that I WANT visible it still doesnt work.

I highly suspect the Gui isn’t totally set up as it should be. It seems as if you do know how to do the script side of this. Again I can’t really test this, I don’t have your Gu. So I’m just guessing here.

1 Like

I haven’t used GUI in this depth before, so I probably made some mistake somewhere. What exactly do you mean, if you dont mind me asking, by the GUI not being setup? What do you do to fully “setup” GUI? Is it just tweaking the properties?

I don’t want to lead you off in a may be wrong direction… It just looks to me you know what you’re doing here scripting. I’m sure this isn’t you first attempt at fixing this. So the next step would be to really question how the Gui itself is set up.

I just wanna ask!

Does your gui’s propertise with proprty IgnoreGuiInset look like this:
image

Yes, it does. Not only did I make it true in the properties tab, I also included it in the script.

Ill probably redo some of the script as well as redo the gui as a whole. Before that, ill do some testing just because at this point I am only continuing to see what the issue is so I can avoid it in the future.

I better do something or im gonna start tweakin

1 Like

tell me, what position does your template have, if not {0,0},{0,0}?
also i rewrite your script:

--services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local plrTeam = player.Team

local parent = script.Parent -- RENAME

local SCORE_BOARD_TAG = "ScoreBoard"

local leftPosition = UDim2.new({0.121, 0},{0.036, 0})
local rightPosition = UDim2.new({0.777, 0},{0.036, 0})
local leftUnseenPosition = UDim2.new({0.121, 0},{-3, 0})
local rightUnseenPosition = UDim2.new({0.777, 0},{-3, 0})

local values = ReplicatedStorage.Values
local events = ReplicatedStorage.Events

local updateMinigameEvent = events.UpdateMinigameEvent
local updateHighestScoreEvent = events.UpdateCurrentHighestScoreEvent

local scoreTable = {
	["Blue"] = {[SCORE_BOARD_TAG] = parent.Blue, ["Value"] = values["Blue Team Score"]},
	["Red"] = {[SCORE_BOARD_TAG] = parent.Red, ["Value"] = values["Red Team Score"]}
}

local updateScoreConnection
local shownHighestScorer
local changeConnections = {}

for i, scoreBoard in CollectionService:GetTagged(SCORE_BOARD_TAG) do
	scoreBoard.Position = leftUnseenPosition
	scoreBoard.Visible = true
end

local function createScoreBoard(plr)
	local scoreValue = values:FindFirstChild(plr.Name .. " Score")
	local targetPosition = (plr == player) and rightUnseenPosition or leftUnseenPosition
	local scoreTemplate = parent.Template
	
	local scoreBoardClone = scoreTemplate:Clone()
	scoreBoardClone.Parent = script.Parent
	scoreBoardClone.Name = plr.Name
	scoreBoardClone.NameLabel.Text = plr.DisplayName
	scoreBoardClone.ScoreLabel.Text = scoreValue.Value
	scoreBoardClone.Position = targetPosition
	scoreBoardClone.Visible = true

	scoreTable[plr] = {
		[SCORE_BOARD_TAG] = scoreBoardClone,
		["Value"] = scoreValue
	}

	print(scoreBoardClone)
	print(scoreBoardClone.Position)
end

local function updateScores(plr)
	local tableForPlr = scoreTable[plr]

	changeConnections[plr] = tableForPlr["Value"].Changed:Connect(function(value)
		tableForPlr[SCORE_BOARD_TAG].ScoreLabel.Text = value
	end)
end

local function removeScoreBoard(plr)
	if changeConnections[plr] then
		changeConnections[plr]:Disconnect()
		changeConnections[plr] = nil
	end

	local board = scoreTable[plr][SCORE_BOARD_TAG]
	board:Destroy()
	scoreTable[plr] = nil
end

local function ShowScoreBoard(show, direction, scoreboard)
	local targetPosition = (direction == "Right") and (show and rightPosition or rightUnseenPosition) or (show and leftPosition or leftUnseenPosition)
	scoreboard.Position = targetPosition
	print(scoreboard.Position)
end

createScoreBoard(player)
ShowScoreBoard(false, "Right", scoreTable[player].ScoreBoard)

for _, team in {player, "Blue", "Red"} do
	task.spawn(function()
		updateScores(team)
	end)
end

task.spawn(function()
	Players.PlayerAdded:Connect(function(plr)
		createScoreBoard(plr)
		updateScores(plr)
	end)

	Players.PlayerRemoving:Connect(function(plr)
		changeConnections[plr]:Disconnect()
		removeScoreBoard(plr)
	end)
end)

local MINIGAMES = {FFA = "FFA", TDM = "TDM"}

local function hideAllScoreboards()
	for _, scoreboard in (CollectionService:GetTagged(SCORE_BOARD_TAG)) do
		local scoreboardData = scoreTable[scoreboard.Name]
		if scoreboardData then
			local scoreboardSide = (scoreboard.Name == player.Name or scoreboard.Name == plrTeam) and "Right" or "Left"
			ShowScoreBoard(false, scoreboardSide, scoreboardData[SCORE_BOARD_TAG])
		end
	end
end
local function handleFFA()
	ShowScoreBoard(true, "Right", scoreTable[player][SCORE_BOARD_TAG])
	if updateScoreConnection then updateScoreConnection:Disconnect() end

	updateScoreConnection = updateHighestScoreEvent.OnClientEvent:Connect(function(highestScorer)
		if shownHighestScorer == highestScorer then return end
		ShowScoreBoard(false, "Left", scoreTable[shownHighestScorer][SCORE_BOARD_TAG])
		ShowScoreBoard(true, "Left", scoreTable[highestScorer][SCORE_BOARD_TAG])
		shownHighestScorer = highestScorer
	end)
end

local function handleTDM()
	local blueTeamBoard = script.Parent.Blue.Name
	local redTeamBoard = script.Parent.Red.Name
	local plrTeam = player.Team.Name
	local leftTeamBoard = (plrTeam == blueTeamBoard) and redTeamBoard or blueTeamBoard
	
	ShowScoreBoard(true, "Right", scoreTable[plrTeam][SCORE_BOARD_TAG])
	ShowScoreBoard(true, "Left", scoreTable[leftTeamBoard][SCORE_BOARD_TAG])
end

local minigameHandlers = {
	[MINIGAMES.FFA] = handleFFA,
	[MINIGAMES.TDM] = handleTDM,
}

updateMinigameEvent.OnClientEvent:Connect(function(minigame)
	hideAllScoreboards()

	local handler = minigameHandlers[minigame]
	handler()
end)
1 Like

this isn’t how to write UDim2’s by the way

it would be UDim2.new(ScaleX, OffsetX, ScaleY, OffsetY)

NOT UDim2.new({ScaleX, OffsetX}, {ScaleY, OffsetY})

this is (confirmed! :derp: ) what’s messing the positioning up

2 Likes