Cant figure out what the problem is
while wait(.5) do
local children = game.Players:GetChildren("Humanoid")
for i = 1, #children do
local hum = children[i] .Character.Humanoid
hum.HeadScale.Value = children[i].leaderstats.Points.Value/50 +1
hum.BodyHeightScale.Value = children[i].leaderstats.Points.Value/50 +1
hum.BodyWidthScale.Value = children[i].leaderstats.Points.Value/50 +1
hum.BodyDepthScale.Value = children[i].leaderstats.Points.Value/50 +1
hum.WalkSpeed = children[i].leaderstats.Points.Value/3.12
hum.JumpPower = children[i].leaderstats.Points.Value
hum.MaxHealth = children[i].leaderstats.Points.Value+25
end
end
was trying to get a simple size script to work.
The attempt to index nil with Humanoid error is telling you that the object that you are trying to grab the Humanoid out of doesn't exist. This line specifically :
local hum = children[i].Character.Humanoid
When a player joins the game, there is an indeterminate amount of time before their character model actually spawns into the world. So between when they join and when their character spawns, the Player.Character property is nil.
Your code does not handle the possibility that the character model is nil, and you are trying to access the humanoid immediately.
A safer approach is not to use a loop, but to observe changes to the leaderstats values and react to those changes. So in your code that creates your leaderstats objects, do something like this :
local Players = game:GetService("Players")
local function updateCharacter(hum : Humanoid, points : number)
local bodyScale = (points / 50) + 1
local walkSpeed = points / 3.12
local jump = points
local health = points + 25
hum.HeadScale.Value = bodyScale
hum.BodyHeightScale.Value = bodyScale
hum.BodyWidthScale.Value = bodyScale
hum.BodyDepthScale.Value = bodyScale
hum.WalkSpeed = walkSpeed
hum.JumpPower = jump
hum.MaxHealth = health
end
Players.PlayerAdded:Connect(function(player)
-- when a player joins the game, give them a leaderstats folder
local leaderstatsFolder = Instance.new("Folder")
leaderstatsFolder.Name = "leaderstats"
local pointsValue = Instance.new("IntValue", leaderstats)
pointsValue.Name = "Points"
pointsValue.Value = 0 -- or load from dataStores
leaderstatsFolder.Parent = player
-- listen for changes to the points and resize the character
pointsValue.Changed:Connect(function(newValue)
-- escape if the character doesn't exist
local character = player.Character
if character then
updateCharacter(character.Humanoid, newValue)
end
end)
-- when the character model spawns into the world, update it immediately with the player's point size
player.CharacterAdded:Connect(function(character)
updateCharacter(character.Humanoid, pointsValue.Value)
end)
end)
Related
I seem to be having an issue of every time I want to pass a function when an event happens such as a Humanoid.Died() or a BindableEvent it runs the function 20+ times, also adding to an IntegerValue that many times as well. I have tried debounces, BindableEvents, connection:Disconnect(), etc. Is there something I'm doing wrong or missing?
Updated original code:
function module.damageHumanoid(attacker, player, humanoid, damage)
local connection
local debounce = false
connection = humanoid.Died:Connect(function()
if not debounce then
debounce = true
connection:Disconnect()
module.onDeath(player)
end
end)
if player:FindFirstChild("damage") == nil then
newFolder = Instance.new("Folder")
newFolder.Name = "damage"
newFolder.Parent = player
end
if newFolder:FindFirstChild(tostring(attacker)) == nil then
record = Instance.new("IntValue")
record.Name = tostring(attacker)
record.Parent = newFolder
end
if record.Value >= 100 then -- sanity check
else
record.Value = record.Value + damage
end
return humanoid:TakeDamage(damage)
end
Which triggers this code:
function module.onDeath(player)
if player:FindFirstChild("damage") ~= nil then
local folder = player:WaitForChild("damage")
local contents = folder:GetChildren()
for i,v in pairs(contents) do
local item = folder[tostring(v)]
damages[item.Name] = item.Value
end
end
local debounce = false
if not debounce then
debounce = true
module.handleKill(damages)
end
end
This is the sword script's function:
function Blow(Hit)
if not Hit or not Hit.Parent or not CheckIfAlive() or not ToolEquipped then
return
end
local RightArm = Character:FindFirstChild("Right Arm") or Character:FindFirstChild("RightHand")
if not RightArm then
return
end
local RightGrip = RightArm:FindFirstChild("RightGrip")
if not RightGrip or (RightGrip.Part0 ~= Handle and RightGrip.Part1 ~= Handle) then
return
end
local character = Hit.Parent
if character == Character then
return
end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health == 0 then
return
end
local player = Players:GetPlayerFromCharacter(character)
if player and player == Player then
return
end
UntagHumanoid(humanoid)
TagHumanoid(humanoid, Player)
module.damageHumanoid(plur, player, humanoid, Damage)
end
So I guess the way I was trying to use debounce isn't correct anymore. I referred to the Roblox documentation and found this: https://create.roblox.com/docs/scripting/scripts/debounce
If anyone would like to know what ended up working for me here it is:
humanoid.Died:Connect(function()
if not humanoid:GetAttribute("Killed") then
humanoid:SetAttribute("Killed", true)
module.onDeath(player)
task.wait(10)
humanoid:SetAttribute("Killed", true)
end
end)
For some reason, when I change a characters hipheight in roblox studio, they are a bit taller than they should be for a bit, then settle down to normal. Here is the code for my hipheight changing script:
--// Configuration
local keybind = "C"
local animationId = 11144547033 --> Replace the number with your animation ID!
--// Variables
local UserInputService = game:GetService("UserInputService")
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local hip = humanoid.HipHeight
local animation = Instance.new("Animation")
animation.AnimationId = 'rbxassetid://' .. animationId
local animationTrack = humanoid:WaitForChild("Animator"):LoadAnimation(animation)
animationTrack.Priority = Enum.AnimationPriority.Action
local crouching = false
--// Functions
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.KeyCode == Enum.KeyCode[keybind] then
if crouching then
humanoid.WalkSpeed = 16
crouching = false
animationTrack:Stop()
character.HumanoidRootPart.CanCollide = true
humanoid.HipHeight = hip
else
humanoid.WalkSpeed = 7
humanoid.HipHeight = 1.5
crouching = true
animationTrack:Play()
end
end
end)
, and what happens
YT Vid
So I am trying to make a game, but cant keep the stats. I already have a working death counter but can't figure out how to save it, it resets everytime I rejoin. Here are two codes I've tried:
1)
local pointsDataStore = game:GetService("DataStoreService"):GetDataStore("Deaths")
game.Players.PlayerAdded:Connect(function(player)
local playerKey = "Player_" .. player.UserId
local success, err = pcall(function()
pointsDataStore:UpdateAsync(playerKey, function(oldValue)
local newValue = oldValue or 0
newValue = newValue + 0
return newValue
end)
end)
end)
2)
local DS = game:GetService("DataStoreService"):GetDataStore("Points")
game.Player.PlayerAdded:connect(plr)
local leaderstats = Instance.new("Model",plr)
leaderstats.Name = "leaderstats"
local currency = Instance.new("IntValue", leaderstats)
currency.Name = "Deaths"
currency.Value = 1
while wait(5) do
DS:SetAsync(plr.userId.."_DS", currency.Value)
end
end)
I would load the value from a datastore when the player joins, then increment it on each death and also save it to the datastore.
Note, that for triggering death, the script is using the Humanoid.Died event.
local deathsStore = game:GetService("DataStoreService"):GetDataStore("Deaths")
function playerAddedHandler(plr)
-- key that is used to store the death value
local playerKey = "Player_" .. plr.UserId
-- Add leader board
local leaderstats = Instance.new("Folder", plr)
leaderstats.Name = "leaderstats"
-- Add "Deaths" column to leader board
local deaths = Instance.new("IntValue", leaderstats)
deaths.Name = "Deaths"
-- Load Deaths value from previous game
deaths.Value = deathsStore:GetAsync(playerKey)
-- Hook up event handler that is triggered when character dies
plr.CharacterAdded:Connect(function(char)
char.Humanoid.Died:Connect(function()
-- increment death value on the leader board
plr.leaderstats.Deaths.Value = plr.leaderstats.Deaths.Value + 1
-- save the value in our deaths datastore
local success, err = pcall(function()
deathsStore:SetAsync(playerKey, plr.leaderstats.Deaths.Value)
end)
end)
end)
end
game.Players.PlayerAdded:Connect(playerAddedHandler) -- call function "playerAddedHandler" every time a player joins the game
Also. Don't forget to enable datastore usage, otherwise it will give you a 403 error in your output. You do that on the roblox website in your game's basic settings:
I am trying to make a door move to a new position using the tween service. The problem is that I keep getting the error, Expected ')' (to close '(' at column 18), got '=', and I don't know why. It highlights the "=" next to "Position" on line 21 in red.
local service = game:GetService("TweenService")
local cupboard1 = game.Workspace.Door1
local cupboard2 = game.Workspace.Door2
local cupboard3 = game.Workspace.Door3
local cupboard4 = game.Workspace.Door4
local handle1 = game.Workspace.Handle1
local handle2 = game.Workspace.Handle2
local handle3 = game.Workspace.Handle3
local handle4 = game.Workspace.Handle4
local info = TweenInfo.new(2)
if state == true then
game.Workspace.Handle1.ClickDetector.MouseClick:connect(function()
local state = false
local change = (Position = Vector3.new(61.831, 4.997, 68.415)) -- door
local change1 = (Position = Vector3.new(63.401, 5.416, 67.89)) -- handle
local change2 = (Orientation = Vector3.new(0, 90, 0)) -- handle
local change3 = (Orientation = Vector3.new(0, 90, 0)) -- door
local tween = service:Create(cupboard1, info, change)
tween:Play()
local tween1 = service:Create(handle1, info, change1)
tween1:Play()
local tween2 = service:Create(handle1, info, change2)
tween2:Play()
local tween3 = service:Create(cupboard1, info, change3)
tween3:Play()
end)
end
if state == false then
game.Workspace.Handle1.ClickDetector.MouseClick:connect(function()
local state = true
local change = (Position = Vector3.new(58.112, 4.997, 66.588)) -- door
local change1 = (Position = Vector3.new(56.631, 5.416, 65.849)) -- handle
local change2 = (Orientation = Vector3.new(0, -135, 0)) -- handle
local change3 = (Orientation = Vector3.new(0, -135, 0)) -- door
local tween = service:Create(cupboard1, info, change)
tween:Play()
local tween1 = service:Create(handle1, info, change1)
tween1:Play()
local tween2 = service:Create(handle1, info, change2)
tween2:Play()
local tween3 = service:Create(cupboard1, info, change3)
tween3:Play()
end)
end
I've tried changing "=" to "==" but it gives me a warning saying Position and Orientation isn't defined.
You are trying to pass a table of changes into your tween. But when you use parenthesis, it is trying to evaluate the line, and this isn't valid lua.
Try changing your parentheses to curly brackets. This will properly assign the changes as a table, which you can pass to your tweens.
local change = { Position = Vector3.new(58.112, 4.997, 66.588)} -- door
local tween = service:Create(cupboard1, info, change)
Here's the error and what I've tried.
Error: Workspace.Part.Script:4: attempt to index nil with 'leaderstats'
My code:
Making Leaderstats:
game.Players.PlayerAdded:Connect(function(plr)
local ls = Instance.new("Model")
ls.Name = "leaderstats"
ls.Parent = plr
local m = Instance.new("IntValue")
m.Name = "Stars"
m.Value = 0
m.Parent = ls
end)
Touch Code:
local collected = false
script.Parent.Touched:Connect(function()
if collected == false then
game.Players.LocalPlayer.leaderstats.Stars.Value = game.Players.LocalPlayer.leaderstats.Stars.Value + 1
end
collected = true
end)
A server script would suit your need better. In a localscript, the change would only appear for the player. Also, it's better practice to use the Players service offered by Roblox. Here's an example:
local Players = game:GetService('Players')
local collected = false
script.Parent.Touched:Connect(function(partTouched)
if partTouched.Parent:IsA('Model') and partTouched.Parent:FindFirstChild('Humanoid') and partTouched:IsA('BasePart') then -- Is this a player? If so, then..
local player = Players:GetPlayerFromCharacter(partTouched.Parent)
if collected == false then
player.leaderstats.Stars.Value += 1 -- shorter syntax
end
collected = true
--script.Parent:Destroy() optional if this part won't be used again.
end
end)
If you're planning to use this for many parts, using a central ModuleScript would save you lots of changing things back and forth: https://developer.roblox.com/en-us/api-reference/class/ModuleScript