Roblox Studio: NPC Humanoid, disabling climbing - lua

I'm very new to Roblox studio and trying to get some basic functionality working. I am spawning some NPCs, and I would like to prevent them from climbing ladders. After reading documentation, it seems I should be able to do this by using Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false). I am inserting that code right after I create the NPC as follows:
local function spawnEnemy()
local enemy = ServerStorage.Enemies.Zombie:Clone()
enemy.Parent = workspace.Enemies
print("Setting climbing to false")
enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)
print(enemy.Humanoid:GetStateEnabled(Enum.HumanoidStateType.Climbing))
enemy.Humanoid.StateEnabledChanged:Connect(function()
print("state changed")
end)
end
The output as I start the game looks like:
Setting climbing to false
false
This is just what I would expect, and also note it does not output "state changed" so I know that no other part of the code is interfering.
However, this doesn't actually prevent the NPC from climbing, and in fact if I immediately type into the console (where it says "Run a command" at the bottom of roblox studio) this command:
print(workspace.Enemies.Zombie.Humanoid:GetStateEnabled(Enum.HumanoidStateType.Climbing))
The output is true.
Why doesn't the variable "stick"? Do I need to put this code somewhere else?

SetStateEnabled doesn't seem to replicate to the client. Your Run-a-command command executes against the client's workspace, and there it is still true.
If you put the same on the server (say add the following into a workspace script):
spawn(function()
while (true) do
print(workspace.Enemies.Zombie.Humanoid:GetStateEnabled(Enum.HumanoidStateType.Climbing))
wait(0.5)
end
end)
...you'll see that on the server, that property is in fact false.
Update:
to set it on the client, you can just hook up a handler on your Enemies folder, that will always set the Humanoid's climbing state for all your zombies:
workspace.Enemies.ChildAdded:Connect(function(child)
if (child.Name == "Zombie") then
child:WaitForChild("Humanoid"):SetStateEnabled(Enum.HumanoidStateType.Climbing, false)
end
end)
just put that above into a LocalScript in StarterPlayerScripts.

Related

My chest script won't add the gold to my stats

game.Players.PlayerAdded:Connect(function(player)
script.Parent.Touched:Connect(function(hit)
if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
local players = game:GetService("Players")
local clone = game.Workspace.Sparkles:Clone()
clone.Parent = game.Workspace
clone.CanCollide = false
clone.Position = script.Parent.Position
script.Parent:Destroy()
wait(1)
clone:Destroy()
local player = game.players.LocalPlayer
players.LocalPlayer.leaderstats.gold.value = 10
end
end)
end)
Here, I'm trying to make a script where if you touch a chest it will give you gold[my stat name] but for some reason, it wont run properly. it wont give me the amount of gold i told it to
From my understanding, you have a function that fires whenever a player joins the game. And then when the part is touched, the part then fires the code you have. I would remove the game.Players.PlayerAdded:Connect(function(player) function as when it get's hit it will fire for every single player who has joined.
But why am I not gaining any gold?
If you are using a server sided script you can't just call game.Players.LocalPlayer as that is client sided. LocalPlayer is an object that is in client sided scripts that tell the client sided script(s) what player they are executing on.
How do I fix this?
First, you already have a statement to decide whether the hit part is a character. So, you can do,
local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
Player.leaderstats.gold.Value += 10
I've fixed a few things in your scripts and removed some things as well. First, I added a += 10 to the gold adding script as if you don't it will just set the gold value to 10 and never add any more.
LocalPlayer is not available to be used on server sided scripts and should only be used on Client sided.
(For future references, in your first initial code you have code that sets the variable of player but under that line you call players. (however, that wouldn't still work. Just trying to provide information about code that's syntax was incorrect.))
When you say script.Parent:Destroy() thats going to delete the script's parent right? So it's going to destroy the script's parent's children which includes the script, which means it can't give you the gold.
Tip: If you ever encounter an error, it might help to put some print statements for logging. For example in your code:
game.Players.PlayerAdded:Connect(function(player)
print("Player has joined!")
Just repeat this for every function, loop, if statement, etc.(with different print messages of course) and then test this and see what gets printed. Also put a print statement after you destroy the script's parent to check if the script stays or not.

How do I make a sell script? (Roblox)

I have been making a Roblox simulator as a side project to learn how to make games, Now I have gotten some help as you can see below but it is still not working. I have got some pictures and videos in these links:
https://flickr.com/photos/195497771#N05
https://vimeo.com/user173767075
Currently my issue is still the title of my question and my tool not working. I changed it to a remote event and now it stopped changing my leaderstats. I have tried a bunch of different solutions but none work. My first script is my tool script. Here it is:
local player = game.Players.LocalPlayer
script.Parent.Activated:Connect(function()
if player.Debounce.Value == false then
game.ReplicatedStorage.Power:FireServer(script.Parent.Values)
local action = script.Parent.Parent.Humanoid:LoadAnimation(script.Parent.Animation)
action:Play()
end
end)
Now, that is in a LocalScript and that works. It prints that it activated and the animation plays. Now my problem is with a script in ServerScriptService not receiving the remote event. I have a print in it but nothing happens. Here is that script:
game.ReplicatedStorage.Power.OnServerEvent:Connct(function(player, valueFolder)
if player.Debounce.Value == false then
player.leaderstats.Sticks.Value += valueFolder.Power.Value
player.Debounce.Value = true
wait(valueFolder.Cooldown.Value)
player.Debounce.Value = false
end
end)
So, for my original question, the sell knows I touch it and it activates the event but nothing changes in the leaderstats. Here is my script to detect when the player touches the sell part.
local sellevent = game.ReplicatedStorage.Sell
script.Parent.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
print("sell fired")
sellevent:Fire()
end
end)
That script works. But that is a server script. Let me know if I should change it to a LocalScript. Now, here is my script that changes the leaderstats, it detects the the event fired but nothing changes in leaderstats.
game.ReplicatedStorage.Sell.Event:Connect(function(player)
print("bindable event fired")
if player ~= nil then
if player.leaderstats.Sticks.Value > 0 then
player.leaderstats.Cash.Value += player.leaderstats.Sticks.Value
player.leaderstats.Sticks.Value = 0
end
end
end)
I gave as much information as I could. If you need anything else I can get more pictures or videos but that is the best I could give. Any help appreciated!
Okay, after watching the video, I might have a hunch as to what's going wrong.
The code in your original question works just fine. If you were to print out the Sticks.Value before adding it to Cash.Value, you'd see that Sticks.Value stays at 0. And you were always adding 0 to Cash.
This is likely because you are using a Tool to increment Sticks.Value, and it is common for Tools to use LocalScripts to hook up logic. When you make changes to the world (or leaderstats values) in LocalScripts, those changes are only present on that client. They are not replicated up to the server. And since all of your cash logic is in server scripts, the Sticks value stays at 0 on the server.
So to fix this, you need to make sure that the code that increments Sticks.Value happens in a Script. And you can do that by using RemoteEvents in the same way you're using your BindableEvent, to communicate from the tool up to a server script.
So in your Tool's LocalScript you'd do something like this :
-- find the RemoteEvent saved in ReplicatedStorage
local stickEvent = game.ReplicatedStorage.GetSticksEvent
-- listen for when the Tool is used
script.Parent.Activated:Connect(function()
-- tell the server to give us some sticks...
stickEvent:FireServer()
end)
Then, in a server Script, listen for that RemoteEvent to fire to give the player some sticks :
-- find the RemoteEvent saved in ReplicatedStorage
local stickEvent = game.ReplicatedStorage.GetSticksEvent
-- listen for when the client tells us that they got some sticks
stickEvent.OnServerEvent:Connect(function(player)
-- give the player some sticks
player.leaderstats.Sticks.Value += 1
end)
Edit - in this most recent version, your Sell script has stopped working because the player argument is nil. In an earlier version of this code, the Touched script passed in the player, but you removed that code and broke the Sell script. So just rollback the script to its earlier state :
script.Parent.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
game.ReplicatedStorage.BindableEvents.Sell:Fire(player)
end
end)

Start a local script from server on Roblox studio

I have a map which I would like to load in the workspace. The map also comes with its own local scripts. However, I don't know where to place them in the player. Maybe I can put them in StarterPlayerScripts and then start them from the server(if Roblox studio has such a functionality).
You can start the local script by simply changing his localscript.Disabled bool value, just change their disabled value to false inside properties when you create them. Example:
localscript.Disabled = true
--Disables localscript
--------------------------------------
localscript.Disabled = false
--Enables it
Check inside the LocalScript for any code statements of script.Parent and put the LocalScript inside whatever the Parent is.

How do I get localplayer data from a leaderboard? (Roblox)

I'm new to Lua and Stack so I apologize in advance.
I'm currently using a tycoon kit to create a Roblox game, and the player's money value only shows up on the leaderboard, but nowhere on the screen. This can make it hard to know how much money you have on console and mobile, so I'm trying to set up a GUI to display the player's amount of money on the screen. Now, setting up the GUI isn't the issue, knowing what to set the text value on the GUI is.
I do not know how to upload am image, but the path in my workspace looks a bit like this:
Players (on the first tab of the workspace)-> Player-> leaderstats-> Cash
I've tried to grab the variable (named "Cash") like this: game.Players.Player.leaderstats.Cash.Value but because I'm not named "Player", it didn't work. I've tried replacing it with LocalPlayer (looked like game.Players.LocalPlayer.leaderstats.Cash.Value), but that also didn't work. It only works when I replace "Player" with my username (game.Players.Username.leaderstats.Cash.Value), but I want this to work for other players besides me.
I've also tried to locate the original variable, but because I did not make the kit I'm at a loss. I've looked in every script that comes with it, but could not find anything.
When I try to set the text to these values, nothing happens. The error message I get falls along the lines of Player is not a valid member of Players.
Any help would be greatly appreciated!
LocalPlayer Is a variable which is only on the client side to get the leaderstats of the LocalPlayer You need to use a local script instead of a normal script
Now i will show you how you can display it first create your "ScreenGui" then create a "TextLabel" under the ScreenGui And finaly create a "LocalScript" Under the TextLabel Now the code should be in the LocalScript
game.Players.LocalPlayer.leaderstats.Cash.Changed:Connect(function(NewValue) --Chnage Cash to your stat
script.Parent.Text = "$"..NewValue
end)
at the start of the script put this:
local plr = game:GetService("Players").LocalPlayer
and at the part where it puts the money on the screen:
(assuming the local script is in the textbox the money is in)
while true do
script.Parent.Text = plr.leaderstats.Cash.Value
wait()
end
and that's all you have to do!
raw paste (just copy and paste this into a localscript inside a textbox)
local plr = game:GetService("Players").LocalPlayer
while true do
script.Parent.Text = plr.leaderstats.Cash.Value
wait()
end
Because LocalPlayer is a Client-Side keyword,
Put this LOCALSCRIPT as a child in the TextLabel. The textlabel should be in a frame. the frame should be in a gui.
Game.Players.LocalPlayer.leaderstats.Cash.Changed:Connect(function(updategui)
script.Parent.Text = "$"..Game.Players.LocalPlayer.leaderstats.Cash.Value
end)

Roblox Studio - Warning/Error when i try to sell the "snow" in my backpack

As you can see on the picture below I can't sell what I have in my backpack when I enter the circle. I get this error/warning and I can't figure out what the problem is. I have found out that the problem happens on line 5: player:WaitForChild
The Error/Warning on line 5: Infinite yield possible on Players.asbjornbonde.PlayerGui:WaitForChild("Stats")
Here is the picture:
Here is my code:
script.Parent.Touched:connect(function(Hit)
local player = game.Players:FindFirstChild(Hit.Parent.Name)
if player then
local leaderstats = player:FindFirstChild("leaderstats")
local PlayerGui = player:WaitForChild("PlayerGui"):WaitForChild("Stats").Backpack
if leaderstats and PlayerGui then
local Cash = leaderstats:FindFirstChild("Cash")
local snow = PlayerGui:FindFirstChild("snow")
if Cash and snow then
if snow.Value <= 0 then
else
Cash.Value = Cash.Value + 2 * snow.Value
snow.Value = 0
script.Parent.DigSound:Play()
script.Disabled = true
wait(0.1)
script.Disabled = false
end
end
end
end
end)
I have used many hours on trying to fix this problem but i really can't. I would appreciate help.
Infinite yield possible on is a warning in Roblox Studio that means there is a possibility that your script could be stuck on that line waiting forever if object it is waiting on doesn't exist and is never created.
As the only WaitForChild that is causing an error is two WaitForChild's joined together I'm guessing the script doesn't like you doing that.
First Solution
If you were to split both WaitForChild's into two different variables it shouldn't give you the error however this is creating another variable for no real reason so I would go for the second solution.
Second Solution
As the player has loaded in and touched the part it's safe to assume the GUI has loaded for them so you can change your WaitForChild to FindFirstChild if you still want to check you didn't get a nil or you can reference it normally: player.PlayerGui.Stats.Backpack
Hope this helps.
Think of WaitForChild() as a loop. It is constantly executing in the background, as fast as the Lua engine can execute it. Wouldn't recommend using this or any sort of un controlled loop in Roblox Lua as the engine doesn't handle it very well.
If this is a server script with a filtering enabled game, the issue is that the server cannot access existing members of PlayerGui. To work around this, you either need to run this code on the client (with the necessary changes), or you'll need to make use of a remote event!

Resources