Hotel events join Ui

how would I code a Ui like this when you join event center in host a event this ui well pops up on your hotel game
Screenshot 2024-07-27 223841

Id use messaging sevice to communicate between the two servers.

okie dokie (sowwy im late)

first

you want your UI fully setup and configured.
make sure you have a ScreenGui parented to StarterGui
under the ScreenGui, you should have a main Frame or alternatively main CanvasGroup that contains the rest of your objects
your button ideally should be a TextButton or ImageButton object with the ZIndex property of the button greater than the ZIndex of all other objects.


i typically recommend using CanvasGroups over Frames because:

  1. CanvasGroups have Group properties (e.g. GroupTransparency, GroupColor) that affect all of their descendant’s properties, which is REALLY useful for scripting effects.
  2. CanvasGroups have the ability to act as a masking layer and it automatically hides anything out of bounds.

these two are demonstrated here:

remember though, CanvasGroups are relatively new and some stuff might be bugged/dysfunctional. you ALWAYS want to make a separate button layer above everything else to serve as a “hitbox” for touch input, etc, when using CanvasGroups. but i’m not an experienced ui designerr or so, i specialize in scripting so ig i can’t speak


second

you want your UI to be visible smoothly on ALL devices right? if not then skip this
for scaling the UI, make sure all of the objects have an AnchorPoint set to 0.5, 0.5. the position of everything will now move, but dw! just move it back and itll work normally

uptill here, this is what you should have:



[VERY VERY BAD UI]

now, you should get this plugin for ease of scaling:

after downloaded, don’t forget to install in Studio if you have it opened:

  1. open the View tab
  2. click Toolbox

    you’ll see Toolbox open on its usual docking location:
  3. follow the steps in the video shown:

    for me, it’s a grayed-out “Installed” button because i already installed it into my place file, however, for you, if you don’t have it installed, it’ll be a blue “Install” button. click that and it’ll install

ok now
you want to open your plugin right?
ok so

  1. open the Plugins tab
  2. you’ll find the AutoScale Lite plugin somewhere there
    i found mine!!
    The image shows a small, square icon or button with a stylized symbol and the text "AutoScale Lite" beneath it, displayed against a dark background. (Captioned by AI)

ok great you found your plugin!! now let’s use it

open the menu, and while having selected ALL elements under the ScreenGui (press Shift to select groups of objects at once, or alternatively Ctrl (for Windows users) to select individual objects) liek this:
This image shows a hierarchical tree view of GUI elements in a software development or interface design tool, displaying components like ScreenGui, CanvasGroup, and various UI elements. (Captioned by AI)
then on the plugin, click the carrot towards the bottom of it and click Unit Conversion:
This image shows a close-up view of a software interface with various icons and tools, including options for "AutoScale Lite" and "Celestial Body Dragger". (Captioned by AI)
you’ll see a popup like this:
This image shows a user interface panel titled "Unit Conversion" with options for adjusting Position and Size using Scale and Offset controls. (Captioned by AI)

i recommend you click the Scale option under Size for well-functioning, intended usage, but you can do whatever you want tbh
after doing this, you might think you’re done. but you’re not unless you want unlocked scaling. this should be what you have right now:

yeah. pretty weird isn’t it? the ASPECT RATIO doesn’t stay locked.
ok so to fix this:

  1. select all the elements like i told u earlier
  2. under the plugin carrot, click Add Constraint
    image
    BOOM!

hell yeah that’s much better
ok good news: scaling is DONE!
bad news: we still have to script now :pensive:

the raw UI .rbxm file that i used (doesn’t contain the code)

to import this, right click on StarterGui and click Insert from File..., and then upload this file:

theUI.rbxm (9.5 KB)

third

ok gang let’s get ready to code lalala


what i had earlier that did NOT frickin work (my dumb ahh ignored that `LocalScript`s in `StarterGui` get refreshed on death and so it pops up whenever u die 💀 do NOT make this mistake like me 💀💀💀)
1. insert a `LocalScript` under the main holding object (either your main `Frame` or main `CanvasGroup` that holds everything else and is parented to the main `ScreenGui` object). 2. name it whatever the heck you want (i named it `Handler`) 3. delete the default: ```lua print("Hello World!") ``` code in it. here's a video demonstrating: ![20240821-1333-53.5553466|video](upload://5DolaFkdJoM8W8RU5Z9YB4MmOhO.mp4) anyways chat, let's define some variables !! the standard scripting convention is to start with defining services if you are planning on using effects, you should define the [`TweenService`](https://create.roblox.com/docs/reference/engine/classes/TweenService) service: ```lua local TS = game:GetService("TweenService") ``` since i'm lazy, i wont be making effects for you. but you can surely watch this tutorial here: https://www.youtube.com/watch?v=9YbTZ8syR4c

you’ll surely be able to find more if this doesn’t help
anyways
now we’ll define paths to variables that we’ll be using.
you should definitely define paths to the objects that you’ll be animating if you consider animating your UI, however, since i’m not, i’m just going to define a path to the button:

local canvas = script.Parent
local button = canvas:WaitForChild("TextButton")

i could also just do:

local button = script.Parent:WaitForChild("TextButton")

next, we’re going to insert a BoolValue under the LocalScript and leave the value false by default.
This image shows a hierarchical view of UI elements in a software development environment, focusing on properties and settings for a component named "Value" within a larger structure. (Captioned by AI)

local hasUsed = script.Value.Value

next, let’s set some preliminary setup. let’s say i want the ui to be visible 5 seconds after the player joins. for that, i want the canvas’s Visible property to be false beforehand!!

canvas.Visible = false

next, let’s move on to the main conditional statement that nests functions within it

if not hasUsed then
	hasUsed = true
	
	task.delay(5, function()
		canvas.Visible = true
	end)
	button.Activated:Connect(function()
		canvas.Visible = false
		-- do yada yada here


		-- for the very end
		script:Destroy() -- please remember to keep this AFTER all other code and effects. for tweens, i recommend you use tween.Completed:Wait() so it doesn't destroy immediately after the tween starts.
	end)
end

function to ensure that it doesn’t show again when we die.
ok i’ll explain this now:

  1. i used the bool-value because the LocalScript may run every time the player dies, but you don’t want that to popup whenever they die do you?
    so, i made a bool-value set to false by default - note that i did not make the bool-value a boolean variable within the code and set it to false at the start; because the code would run everytime the player dies, and the boolean would keep getting set to false and the code would keep running, which isn’t intended behavior and ruins the literal point.
  2. i used task.delay() to schedule the function/coroutine for making the canvas visible to be called or resumed on the next Heartbeat after my given duration, which was 5 seconds, has passed, without throttling.
    therefore, we were able to achieve the canvas being visible 5 seconds after the player has joined via task.delay().
  3. i used a function that connects to button.Activated that fires when the button is “activated”, or clicked. this property is only available for TextButtons and ImageButtons (in relation to UI objects—ofc it’s there with Tools, etc); else you’d have to use MouseButton1Click or MouseButton1Down if it’s a separate object. and yes, dw, BOTH of these are mobile compatible as far as i have tested.
  4. i added script:Destroy() within the button-activated function (which will only destroy it FOR the localplayer) just for extra security to make sure it doesn’t show again
----

ok now working stuff:

  1. insert a new LocalScript in StarterPlayer > StarterPlayerScripts
  2. name it whatever the sigma you want (i named it Handler but it really doesn’t matter)
    what you should have so far:
    The image shows a file directory structure with a folder named "StarterPlayer" containing a subfolder called "StarterPlayerScripts". (Captioned by AI)
  3. insert a new BoolValue into the main canvas/frame in your UI holding all other objects.

okk now we need to script!!

in the LocalScript:

delete the usual

print("Hello World!")

code

yaaay fresh new empty script!!!

the standard convention of coding is to start by defining any services you need.
the first service that we will need, is the Players service!
you can define it like this:

local Players = game:GetService("Players")

you can define any more services you might need!
if you are planning on using effects, you should define the TweenService service:

local TS = game:GetService("TweenService")

since i’m lazy, i wont be making effects for you. but you can surely watch this tutorial here:

you’ll surely be able to find more if this doesn’t help
anyways

okk now let’s define paths to actual variables and objects instead of services
since this is a LocalScript, we can directly access the player object via Players.LocalPlayer as shown below:

local player = Players.LocalPlayer

now we need to access the player’s PlayerGui object!

local playerGui = player:FindFirstChild("PlayerGui")

next, let’s access our ScreenGui object under the player’s PlayerGui object:

local ui = playerGui:WaitForChild("[replace this with the name of your ScreenGui object]")

for me, the name of my ScreenGui object is literally “ScreenGui”! :sweat_smile: thus, i will reference it like this:

local ui = playerGui:WaitForChild("ScreenGui")

okk, let’s access all other objects that we need. you’ve pretty much got the hang of it so yeah. our most priority object will be the button object since we need that to connect to a click function. you can also reference any other objects you’ll need for animation and effects.
for me, i’ll firstly reference my main canvas since that’s where all my other priority objects are parented to and i don’t want to have to keep typing ui:WaitForChild("CanvasGroup") when i can just type canvas !!
i’ll also reference the path to the button object that we’ll need:

local canvas = ui:WaitForChild("CanvasGroup") -- or whatever ur main holding object is named
local button = canvas:WaitForChild("TextButton") -- or whatever the path to ur button is

now that we have that referenced, we also need to reference the BoolValue that we created earlier. in the reference, you shouldn’t just reference the instance but the Value property of the instance since that’s what we’re changing (else whenever you’re changing its property, you’ll have to add a .Value to the variable name):

local hasUsed = canvas:WaitForChild("Value").Value

this should also be a great time to mention that you should set the main frame/canvas’s Visible property to false:


ok back at coding again, let’s script some preliminary setup. the main setup we need for this is to ensure that the main frame/canvas’s visibility is false:

canvas.Visible = false

let’s get to the main code now!

we start off by creating a conditional statement that checks if the value of the hasUsed variable is false, and if it is, then we make the value of the hasUsed variable true:

if not hasUsed then
	hasUsed = true
end

this works off of basic “debounce” coding logic, except we don’t ever set the variable to false again.

now, i want the popup to show 5 seconds after i join.

for this, within the conditional statement, we’ll nest a task.delay() function (which schedules a function/coroutine to be called or resumed on the next Heartbeat after the given duration (in seconds, which in this case, we’re targeting 5 seconds) has passed, without throttling) such that after 5 seconds, a function will be called to make the canvas visible:

task.delay(5, function()
	canvas.Visible = true
end)

let’s put this within the conditional statement now:

if not hasUsed then
	hasUsed = true

	task.delay(5, function()
		canvas.Visible = true
	end)
end

now, we want another function such that when the button is clicked (for which we’ll use a property available solely for TextButtons and ImageButtons only [when talking about UI objects; ofc it’s available for Tools, etc]—button.Activated—to determine when the button is clicked. alternatively, if you’re not using a TextButton or ImageButton for the button, you can just use MouseButton1Click or MouseButton1Down (and dw, both are mobile compatible as far as i have tested):

button.Activated:Connect(function()
	canvas.Visible = false
	-- do yada yada here
end)

let’s put this within the conditional statement now:

if not hasUsed then
	hasUsed = true

	task.delay(5, function()
		canvas.Visible = true
	end)
	button.Activated:Connect(function()
		canvas.Visible = false
		-- do yada yada here
	end)
end

so, this should be our whole code:

local Players = game:GetService("Players")
local player = Players.LocalPlayer
local playerGui = player:FindFirstChild("PlayerGui")
local ui = playerGui:WaitForChild("ScreenGui") -- or whatever ur ScreenGui object is named

local canvas = ui:WaitForChild("CanvasGroup") -- or whatever ur main holding object is named
local button = canvas:WaitForChild("TextButton") -- or whatever the path to ur button is

local hasUsed = canvas:WaitForChild("Value").Value

canvas.Visible = false

if not hasUsed then
	hasUsed = true

	task.delay(5, function()
		canvas.Visible = true
	end)
	button.Activated:Connect(function()
		canvas.Visible = false
		-- do yada yada here
	end)
end

anyways, for the rest of your code, depending on what you have to do on the button click, you can do it under the

-- do yada yada here

comment. for example, you can use TeleportService (remember to save this as a service variable at the TOP of your LocalScript near where i explained you can store the TweenService service) to teleport the player to another Place experience, or you can use :PivotTo() on the character’s HumanoidRootPart to teleport the character to a CFrame within the game, etc.

now please remember that in the code i’ve provided, you’re REQUIRED to click the button to make the UI go away. it’s pretty simple to script some sort of timeout so you can definitely do that.

and again, feel free to use TweenService to animate your UI!

YAAAY YOU DID IT!!!

here’s a video showing it functional:

if you want to skip through all my instructions and 4 hours of typing, recording, coding, debugging, formatting, ui designing, etc (i’ll be :frowning: but)

here’s the .rbxm file:

myTutorialMainModel.rbxm (12.5 KB)

you can just right-click on Workspace, and then click Insert from File... and upload the file above. afterwards, i added an instructions page that you can read and follow instructions to setup.

OR

here’s the free model i uploaded’s creator marketplace link:

OR

here’s the place file i used for the demo with everything working:

uipopuponjoinDemo.rbxl (65.4 KB)

you can just download it, then open it, and boom!

uhhh enjoy! (mb i made it too long :pensive:)

and if you even read this mark me as solution pslspslpslspsl :pleading_face: i spent hours on this for u

2 Likes