Shortcutting script, touch function - lua

I'm trying to have a better/shorter way to decrease any lag and use less effort, as if I need to change anything in the script, I'll need to do it for each one.
Is there a better way of having short?
I tried having them the "Glass1's" the same name and the "Glass2's" the same name, but it worked on the first one only, I wish I clarified it.
Here is my code:
local End = script.Parent.End
local Start = script.Parent.Start
local Glass = script.Parent
--Glass1/1-8 are the glasses that fall if touched and they change color to red
local function TouchedGlass11(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass11
num.Anchored = false
num.BrickColor = BrickColor.Red()
wait(2)
num:Destroy()
else return
end
end
Glass.Glass11.Touched:Connect(TouchedGlass11)
local function TouchedGlass12(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass12
num.Anchored = false
num.BrickColor = BrickColor.Red()
wait(2)
num:Destroy()
else return
end
end
Glass.Glass12.Touched:Connect(TouchedGlass12)
local function TouchedGlass13(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass13
num.Anchored = false
num.BrickColor = BrickColor.Red()
wait(2)
num:Destroy()
else return
end
end
Glass.Glass13.Touched:Connect(TouchedGlass13)
local function TouchedGlass14(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass14
num.Anchored = false
num.BrickColor = BrickColor.Red()
wait(2)
num:Destroy()
else return
end
end
Glass.Glass14.Touched:Connect(TouchedGlass14)
--then I'll do Glass2/1-8 which just turn the brick to green.
local function TouchedGlass21(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass21
num.BrickColor = BrickColor.Green()
else return
end
end
Glass.Glass21.Touched:Connect(TouchedGlass21)
local function TouchedGlass22(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass22
num.BrickColor = BrickColor.Green()
else return
end
end
Glass.Glass22.Touched:Connect(TouchedGlass22)
local function TouchedGlass23(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass23
num.BrickColor = BrickColor.Green()
else return
end
end
Glass.Glass23.Touched:Connect(TouchedGlass23)
local function TouchedGlass24(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = Glass.Glass24
num.BrickColor = BrickColor.Green()
else return
end
end
Glass.Glass24.Touched:Connect(TouchedGlass24)
--Does anyone know a better way?
please note: there is 8 glasses in both "Glass2" and "Glass1" but I'll be adding more soon, that's why I'm looking for an easier way.

Looking at your code it's pretty easy to spot that your using a lot of touched functions.
You can condense this significantly by using a for loop which iterates through each of the parts in script.Parent.
local glass = script.Parent
-- iterate through each child and assign the child to the variable object
for _, object in pairs(glass:GetChildren()) do
-- Make sure this child of script.Parent is actually a part.
if object:IsA("Part") then
object.Touched:Connect(function(hit)
local partParent = hit.Parent
local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
local num = object
num.Anchored = false
num.BrickColor = BrickColor.Red()
wait(2)
num:Destroy()
end
end)
end
end
You also shouldn't need to have a return in your touched functions.

Related

Attempt to index boolean with 'Health'

I made a punch script, with a hitbox part, but it doesn't gives damage and i have an error in the output called "Attempt to index boolean with 'Health'", but the humanoid exists and his properties too, what is happening? Can i fix that? Code here:
local rep = game:GetService("ReplicatedStorage")
local debounceDMG = true
rep.Combate.Soco.OnServerEvent:Connect(function(plr)
local math = math.random(1,2)
local char = plr.Character or plr.CharacterAdded:Wait()
local Humanoid = char.Humanoid
local lanim = char.Humanoid:LoadAnimation(script.Left)
local lanim1 = char.Humanoid:LoadAnimation(script.Animation)
local hitbox = Instance.new("Part")
hitbox.Parent = workspace
hitbox.Transparency = 0
hitbox.Anchored = true
hitbox.CanCollide = false
hitbox.Size = Vector3.new(2.5,2.5,2.5)
hitbox.CanTouch = true
local c = game:GetService("RunService").Heartbeat:Connect(function()
if math == 2 then
hitbox.Position = char.LeftHand.Position
elseif math == 1 then
hitbox.Position = char.RightHand.Position
end
end)
if math == 2 then
lanim:Play()
elseif math == 1 then
lanim1:Play()
end
hitbox.Touched:Connect(function(hit)
local hum = hit.Parent:FindFirstChild("Humanoid") ~= Humanoid
if hum then
hum.Health -= 5
end
end)
task.wait(.3)
hitbox:Destroy()
c:Disconnect()
end)
This line:
local hum = hit.Parent:FindFirstChild("Humanoid") ~= Humanoid
assigns a boolean to hum, depending on whether the return value from FindFirstChild is not equal to Humanoid.
Because hum is a boolean, that's why you get the Attempt to index boolean with 'Health' runtime error on this line:
hum.Health -= 5
First, I'd recommend adding this hot comment to the very top of your script:
--!strict. Then, Luau LSP (if you're using Visual Studio Code) and/or Roblox Studio can tell you about this mistake before your code even runs. It's really nice to see the red squiggle appear and tell you more precisely what's wrong.
Second, you probably mean for the hum assignment to simply be:
local hum = hit.Parent:FindFirstChild("Humanoid")

Check if tool is equipped

How do I determine in a condition if a tool is currently equipped?
The following is the LocalScript in my tool, called "Axe".
local UIS = game:GetService("UserInputService")
local Animation = script.Chop
local Player = game.Players.LocalPlayer
local Character = Player.Character
UIS.InputBegan:Connect(function(input, gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local A = Humanoid:LoadAnimation(Animation)
A:Play()
end
end)
Tools are parented under the character when equipped. Henceforth, you can just write the following condition:
if Player.Character:FindFirstChild("Axe") ~= nil then
you can make a variable that can store a boolean and changes when the tool is equipped or unequipped
local isEquipped = false
Tool.Equipped:Connect(function()
isEquipped = true
end)
Tool.Unequipped:Connect(function()
isEquipped = false
end)

Debounce is not a valid member of Folder

Alright so I got this script from a tutorial and this is what I typed for the script Remotes
local replicatedStorage = game:GetService("ReplicatedStorage")
local remoteData = game:GetService("ServerStorage"):WaitForChild("RemoteData")
local cooldown = 1
replicatedStorage.Remotes.Lift.OnServerEvent:Connect(function(player)
print("event launched")
if not remoteData:FindFirstChild(player.Name) then return "NoFolder" end
local debounce = remoteData[player.Name].Debounce
if not debounce then
debounce.Value = true
player.leaderstats.Power.Value = player.leaderstats.Power.Value + 5 * (player.leaderstats.Prestiges.Value + 1)
wait(cooldown)
debounce.Value = false
end
end)
but I have seem to get the error which is
Debounce is not a valid member of Folder "ServerStorage.RemoteData.OmegaHero2010"
here are some other scripts
Stats
local serverStorage = game:GetService("ServerStorage")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local power = Instance.new("NumberValue")
power.Name = "Power"
power.Parent = leaderstats
local prestige = Instance.new("NumberValue")
prestige.Name = "Prestiges"
prestige.Parent = leaderstats
local dataFolder = Instance.new("Folder")
dataFolder.Name = player.Name
dataFolder.Parent = serverStorage.RemoteData
local debounce = Instance.new("BoolValue")
debounce.Parent = dataFolder
end)
Module
local module = {}
local replicatedStorage = game:GetService("ReplicatedStorage")
function module.Lift()
replicatedStorage.Remotes.Lift:FireServer()
end
return module
Local Script
local module = require(script.Parent:WaitForChild("ModuleScript"))
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
script.Parent.Activated:Connect(function()
module.Lift()
end)
what is the problem here?
The line local debounce = remoteData[player.Name].Debounce is failing to find the child named "Debounce".
So, looking at how you created the BoolValue in ServerScriptService :
local debounce = Instance.new("BoolValue")
debounce.Parent = dataFolder
You never set the Name property. So there is a BoolValue in the player's folder but it is named "BoolValue", not "Debounce". To fix your error, just add the line to set the Name.
debounce.Name = "Debounce"

Attempt to index nil with Position

I'm trying to do something like a spear throw and I'm so confused. It says:
ServerScriptService.FireMagic.FireSpear:16: attempt to index nil with 'Position'
Anyways, here's the LocalScript code:
wait(1)
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Mouse = Player:GetMouse()
local rp = game:GetService("ReplicatedStorage")
local FireSpear = rp:WaitForChild("FireRemote")
local UIS = game:GetService("UserInputService")
local debounce = true
local cd = 10
UIS.InputBegan:Connect(function(input, isTyping)
if isTyping then
return
elseif input.KeyCode == Enum.KeyCode.E and debounce and Character then
debounce = false
FireSpear:FireServer()
wait(cd)
debounce = true
end
end)
and the Script:
wait(1)
local rp = game:GetService("ReplicatedStorage")
local ss = game:GetService("ServerStorage")
local Debris = game:GetService("Debris")
local ssFireSpear = ss.FireMagic:WaitForChild("ssFireSpear")
local FireRemote = rp:WaitForChild("FireRemote")
local UhTable = {}
local function LookatMouse(Mouse, RootPart)
local bodyG = Instance.new("BodyGyro")
bodyG.MaxTorque = Vector3.new(0, 500000, 0)
bodyG.P = 10000
bodyG.CFrame = CFrame.new(RootPart.Position, Mouse.Position)
bodyG.Parent = RootPart
Debris:AddItem(bodyG, 1)
end
local function MoveTowardsMouse(Mouse, Main)
local bodyV = Instance.new("BodyVelocity")
bodyV.MaxForce = Vector3.new(500000, 500000, 500000)
bodyV.Velocity = CFrame.new(Main.Position, Mouse.Position).LookVector * 100
bodyV.Parent = Main
local bodyG = Instance.new("BodyGyro")
bodyG.MaxTorque = Vector3.new(500000, 500000, 500000)
bodyG.P = 10000
bodyG.CFrame = CFrame.new(Main.Position, Mouse.Position)
bodyG.Parent = Main
end
FireRemote.OnServerEvent:Connect(function(Player, Mouse_CFrame)
if UhTable[Player.Name] == true then
return
end
UhTable[Player.Name] = true
local Character = Player.Character
local RootPart = Character:WaitForChild("HumanoidRootPart")
local folder = workspace:FindFirstChild("DebrisFolder") or Instance.new("Folder",workspace)
folder.Name = "DebrisFolder"
local RightHand = Character:WaitForChild("RightHand")
local FireSpear = ssFireSpear:Clone()
local Handle = FireSpear:WaitForChild("Handle")
local Hitbox = FireSpear:WaitForChild("Hitbox")
local Mesh = FireSpear:WaitForChild("Mesh")
FireSpear:SetPrimaryPartCFrame(RightHand.CFrame)
FireSpear.Parent = folder
local weld = Instance.new("Motor6D")
weld.Parent = Handle
weld.Part0 = RightHand
weld.Part1 = Handle
Hitbox:SetNetworkOwner(nil)
local function MakeStuffHappen()
spawn(function()
LookatMouse(Mouse_CFrame,RootPart)
wait(.6)
weld:Destroy()
MoveTowardsMouse(Mouse_CFrame,Hitbox)
end)
end
MakeStuffHappen()
end)
I'm following a tutorial but I don't know how the issue got there.
Your error is pointing to the fact that you are trying to reference fields on an object that doesn't exist. In this case, it's the ´Mouse´ object, which you never supplied from the client.
To fix this, pass the mouse information in when you call the RemoteEvent's FireServer() function.
UIS.InputBegan:Connect(function(input, isTyping)
if isTyping then
return
elseif input.KeyCode == Enum.KeyCode.E and debounce and Character then
debounce = false
local mouseCFrame = Mouse.Hit
FireSpear:FireServer(mouseCFrame)
wait(cd)
debounce = true
end
end)

Roblox Lua cannot access modulescript function

I've been trying to connect a ModuleScript to a server Script, and it's throwing the error: Workspace.Script:6: attempt to call field 'check3' (a nil value)
ModuleScript
local GunStats = {}
local part = workspace:WaitForChild('Mosin'):WaitForChild("Union")
local billboard = workspace:WaitForChild('BillboardPart'):WaitForChild('BillboardGui')
local uis = game:GetService("UserInputService")
local Ekey = Enum.KeyCode.E
local check = false
local start = tick()
local function onpress(action1)
if check then
part.BrickColor = BrickColor.new("Black")
end
end
local function isKeydown(startTime)
return uis:IsKeyDown(startTime) and startTime - tick() <= 5
end
local function Input(input, gameprocessed)
if isKeydown(Ekey) then
print("h")
else
print("n")
end
start = tick()
end
game.Players.PlayerAdded:Connect(function(player)
local character = player.Character or player.CharacterAdded:Wait()
local humRoot = character:WaitForChild("HumanoidRootPart")
uis.InputBegan:Connect(Input)
GunStats.check3 = function()
while wait() do
if (humRoot.Position - part.Position).Magnitude < 5 then
print("IN RANGE")
check = true
billboard.Enabled = true
repeat wait() until (humRoot.Position - part.Position).Magnitude >= 5
elseif (humRoot.Position - part.Position).Magnitude > 5 and check then
check = false
print("OUT OF")
billboard.Enabled = false
end
end
end
end)
return GunStats
Server Script:
local players = game:GetService("Players")
local serverStorage = game.ServerStorage
local gunStats = require(serverStorage:WaitForChild("ModuleScript"))
game.Players.PlayerAdded:Connect(function(players)
gunStats.check3(players)
end)
This issue is because the gunStats.check3() function isn't defined on the GunStats object until after a player joins. I would restructure your ModuleScript so that GunStats.check3() is defined right away :
--[[ define all your helper functions up here ... ]]
local GunStats = {}
function GunStats.check3(player)
-- access the humanoid
local character = player.Character or player.CharacterAdded:Wait()
local humRoot = character:WaitForChild("HumanoidRootPart")
-- do the checks
end
return GunStats

Resources