Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

"Player..Name" on Gui not displaying?

Asked by
Aozwel 71
4 years ago

Hey there,

Just a heads up i'm super new to scripting started about 5 hours ago,

So i've been working on a Dialog Gui like in the game Camping and other short story games.

I've been stuck on this part for some time now i feel like its super close but i'm missing some wording/code that i have not yet been made aware of and was wondering if anyone can point me in the right direction?

So i've created a Part when players touch it i'm trying to make the Gui say there Player name followed by some text and i believed i've written it somewhat right but not sure whats wrong

-- Roblox services local dialogGui = script.Parent local ReplicatedStorage = game:GetService("ReplicatedStorage") local object = script.Parent local Players = game:GetService("Players")

local part = script.Parent.Parent.Parent.Parent.Parent local function onTouched(part) local player = Players:GetPlayerFromCharacter(part.Parent) if not player then return end part.Touched:Connect(onTouched)

    wait(1)

-- Require module local TypeWriter = require(ReplicatedStorage:WaitForChild("TypeWriter"))

TypeWriter.typeWrite(script.Parent, "Hey! "..player.Name.."Found the key!") wait(1)

end


local object = script.Parent

object.AnchorPoint = Vector2.new(0, 0) object.Position = UDim2.new{0, 0},{0, 0}

object:TweenPosition(UDim2.new(0, 0, -10.04, 0), Enum.EasingDirection.In, Enum.EasingStyle.Sine,0.5)

wait(2)

script.parent.Visible = false if script.parent.visible == false then print("Worked2!")

end

Thanks, Any questions or information needed ill be happy to help!

0
Are there errors in the output? OBenjOne 190 — 4y
0
Should of just put the part that has an error User#29320 0 — 4y
0
Nope :/ it just skips all the way through and prints the "Worked2" so its missing the ..Player.Name.. Thingy completely Aozwel 71 — 4y
0
The area were it "Errors" but shows nothing in output is around here: local Players = game:GetService("Players") local part = script.Parent.Parent.Parent.Parent.Parent local function onTouched(part) local player = Players:GetPlayerFromCharacter(part.Parent) if not player then return end part.Touched:Connect(onTouched) wait(1) -- Require module local TypeWriter = require(ReplicatedSto Aozwel 71 — 4y
0
wow dang you learned a lot in 5 hours.... greatneil80 2647 — 4y

3 answers

Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

This:

object.Position = UDim2.new{0, 0},{0, 0}

should be this:

object.Position = UDim2.new(0, 0, 0, 0)

Use of Parent

There is no need to call parent after parent. It works and all, but what happens when you move the script? You have to go back and call parent after parent.

The best practice is to use Parent in family trees as less as possible.

Example:

-- inefficient
local model = script.Parent
local part = script.Parent.Part

-- efficient
local model = script.Parent
local part = model.Parent

If I were to move the script elsewhere, the part variable in the inefficient example would have to be changed as well as the model variable. In the efficient example, however, all I have to edit is the model variable.

Debounces

When someone touches your key, it'll fire like hundreds of times because the touched event is very sensitive. Also, :GetPlayersFromCharacter() can lag up really bad with it firing that much. You can either add a time limit or disconnect it once a player has found it.

  • Time limit
local debounce = true
part.Touched:Connect(function(part)

    if (debounce) then --check if debounce is true

        debounce = false --sets it to false

        local hum = part.Parent:FindFirstChildOfClass('Humanoid')
        if (hum) then
            local plr = Players:GetPlayerFromCharacter(hum.Parent)
        end

    end

    wait(1) --waits 1 second
    debounce = true --sets it back to true

end)

So debounce has to be true in order for the touched event to trigger everything. If we set it to false, it will not fire that expensive function :GetPlayersFromCharacter().

  • Disconnect
connection = part.Touched:Connect(function(part)
    local hum = part.Parent:FindFirstChildOfClass('Humanoid')
    if (hum) then
        local player = game.Players:GetPlayerFromCharacter(hum.Parent)
        if (player) then
            connection:Disconnect()
        end
    end
end)

This is efficient if you have no NPC's or objects with humanoids in your game that can run into the part. It will only run onces, which is probably what you are looking for with a game like Camping.

Requiring Modules

You do not have to add so much waits to your code. It is a waste of time and space there is no need for it. You can require the module at the start of the script rather than requiring it when you need it. This will make it easier to find bugs and overall cleaner code in my opinion.

Ad
Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

From what I could decode, your formatted script is this:

local dialogGui = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage") 
local object = script.Parent
local Players = game:GetService("Players")

local part = script.Parent.Parent.Parent.Parent.Parent 
local function onTouched(part) 
    local player = Players:GetPlayerFromCharacter(part.Parent) 
    if not player then return end 
    part.Touched:Connect(onTouched)
    wait(1)
    local TypeWriter = require(ReplicatedStorage:WaitForChild("TypeWriter"))
    TypeWriter.typeWrite(script.Parent, "Hey! "..player.Name.."Found the key!") wait(1)
end

local object = script.Parent
object.AnchorPoint = Vector2.new(0, 0) object.Position = UDim2.new{0, 0},{0, 0}
object:TweenPosition(UDim2.new(0, 0, -10.04, 0), Enum.EasingDirection.In, Enum.EasingStyle.Sine,0.5)
wait(2)
script.parent.Visible = false 
if script.parent.visible == false then print("Worked2!")end

(BTW, you can use the little blue button that says "lua" above the edit field to make your code appear in a fancy block like above)

From your question, it seems like you're a little confused on how functions (ex "local function onTouched()") and events work.

Functions are basically little bits of code that you can separate out of your main program to avoid duplicated code and improve organization. They're defined like your "onTouched()" function. Take this function, for example:

function literallyWhateverYouWantItToBeNamed()
    print("Hey, I ran!")
end

What would be the output if you ran just that snippet? At a glance, you'd think it would be Hey, I ran! right? Wrong. The problem is that the function is never CALLED. Functions will never run if you never call them! So, how do you call a function? Easy! Just write its name with '()' after it to let the program know it's a function:

function literallyWhateverYouWantItToBeNamed()
    print("Hey, I ran!")
end
literallyWhateverYouWantItToBeNamed()

Output: Hey, I ran! Now the output is correct! As a side note, you can pass variables (local ...) to change how they function, but I'll let you read up on.

Events in roblox work closely with functions. Basically, all they do is execute a function whenever the event is "triggered". In your case, you want to execute your custom function "onTouched" when the event "Touched" is triggered on "part". You "connect" your function to the event to let it know what to execute when it is fired with ":Connect(function)".(Some more advanced reading on events - they're the best thing since sliced bread!)

Now, lets see why your code doesn't work.

To start off, your onTouched function is never called inside your main body of code (Remember - functions don't run unless called!), meaning that what you are basically running is:

local dialogGui = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage") 
local object = script.Parent
local Players = game:GetService("Players")

--onTouched may as well not be here!

local object = script.Parent
object.AnchorPoint = Vector2.new(0, 0) object.Position = UDim2.new{0, 0},{0, 0}
object:TweenPosition(UDim2.new(0, 0, -10.04, 0), Enum.EasingDirection.In, Enum.EasingStyle.Sine,0.5)
wait(2)
script.parent.Visible = false 
if script.parent.visible == false then print("Worked2!")end

That isn't to say however, that you NEED to call a function in code explicitly (using "functionname()"). If you link it to an event using :Connect(), it will be run then - when you actually want it to. Problem is, you've put the line of code that actually connects your function to the touched event inside a function that never runs! Good thing is, is that it's a simple fix: just place the "part.Touched:Connect(onTouched)" after the function, like this:

local function onTouched(part) 
    local player = Players:GetPlayerFromCharacter(part.Parent) 
    if not player then return end 
    wait(1)
    local TypeWriter = require(ReplicatedStorage:WaitForChild("TypeWriter"))
    TypeWriter.typeWrite(script.Parent, "Hey! "..player.Name.."Found the key!") wait(1)
end
part.Touched:Connect(onTouched)

While you're at it, I would recommend that you place all your functions before your main code starts (looking for a specific function in hundred lines of code isn't fun).

---EDIT:--- Ah, I missed that this is a GUI. GUI elements (Like buttons, labels, etc) have different events to physical parts like bricks, which is why the "Touched" event won't work - it's only for physical parts. If the label you're using right now is supposed to be a button a for a user to press, I'd heavily recommend replacing it with an actual TextButton - the events for which can be found here. If you scroll to the bottom of the page, you can see all of the events that you can link to with :Connect(), as well as helpful descriptions of when they trigger (Note: Almost everything in Roblox is documented in this way on developer.roblox.com - super helpful!). Looking at the events under GuiButton - which is what a TextButton basically is - you probably want "MouseButton1Click", which fires when someone clicks on the button. Linking to this is just as you would think:

--Replace:
part.Touched:Connect(...)

--With
part.MouseButton1Click:Connect(...)

This is an event SPECIFIC to Buttons, so it won't work if you don't change the label to a button.

As a side note, I would also try to start getting in the habit of naming variables to describe what they hold. For example, a better name for "part" - which holds your textlabel/button would maybe be "playerFoundKeyButton" - which describes what the variable is and what it does.

Hope I helped, and good luck!

0
Firstly thanks for the long and detailed reply @whenallthepigsfly i applied your corrections and get this error in the output i assume its something small missing? "Touched is not a valid member of TextLabel" Aozwel 71 — 4y
0
I've edited my answer to address this. whenallthepigsfly 541 — 4y
Log in to vote
0
Answered by 4 years ago

You havenĀ“t asked the script to collect the name of the player that touched it.

Answer this question