Resetting a script after game round? - lua

When the game timer ends it kills the players & resets the teams and sends them to spawn to choose a Team again... idk how to reset the script to start from the beginning and have reset all the values and functions called... I tried making a copy of the script and destroy the current one with script:Destroy() but doesn't work & continues with the same function so breaks my game when the players choose the teams again & respawn.
-- Get Service Variables
local Teams = game:GetService("Teams")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local plr = game:GetService("Players").LocalPlayer
-- Wait for Child Variables
local TeamResetter = game.ReplicatedStorage.TeamResetter
local TimeCountdown = ReplicatedStorage:WaitForChild("Timer")
--Scripts Resets the entire script after GameTime is up
local function ResetGame(Player,Teams)
local copy = script:Clone()
copy.Parent = script.Parent
script:Destroy()
end
-- Destroy Gate when thieves touch it
game.Workspace.CarGate4.GateRod.Touched:Connect(function(hit,Player)
local h = hit.Parent:FindFirstChild("Humanoid")
if h ~= nil then
local n = hit.Parent
local p = game.Players:FindFirstChild(n.Name)
if p.Team.Name == "Thieves" then
game.Workspace.CarGate4.GateRod:Destroy()
end
end
end)
--Thieves function for winning
--[[humanoid.Seated:Connect(function(active,currentSeat, Player, Team)
if active then
if currentSeat.Name == "DriveSeat" then
if Player.TeamColor == game.Teams.Thieves.TeamColor then
game.StarterGui.ThiefWinScreen.Frame.TextLabel.Script.Disabled = false
end
end
end
end)]]
local function PoliceWinReset(Player,Team)
game.StarterGui.PoliceWinScreen.Frame.TextLabel.Script.Disabled = false
wait(2)
for i,v in pairs(game.Teams.Thieves:GetPlayers()) do
Player.TeamColor = game.Teams.ChoosingTeam.TeamColor
game.StarterGui.ThiefWinScreen.Frame.TextLabel.KillPlayer.Disabled = false
Player.Character:BreakJoints()
game.StarterGui.ChooseTeamGUI.Enabled = true
ResetGame(Player,Teams)
end
for i,v in pairs(game.Teams.Police:GetPlayers()) do
Player.TeamColor = game.Teams.ChoosingTeam.TeamColor
game.StarterGui.PoliceWinScreen.Frame.TextLabel.KillPlayer.Disabled = false
Player.Character:BreakJoints()
game.StarterGui.ChooseTeamGUI.Enabled = true
ResetGame(Player,Teams)
end
end
--Starts Global timer for game after user chooses a team & Police win code
--Resets Player Teams and respawns them back at spawn and have to choose a team again
local function PlayGame(Player, Team)
local timerAmount = 120
local timerText = ""
while timerAmount >= 0 do
TimeCountdown:FireAllClients(timerAmount,timerText)
wait(1)
timerAmount -= 1
if timerAmount == 0 then
PoliceWinReset(Player,Team)
end
end
return timerAmount
end
--Checks wether the user is on the Thieves or Police Teama
local function Thieves_Police(Player, Team)
if Player.TeamColor == game.Teams.Police.TeamColor then
game.StarterGui.ChooseTeamGUI.Enabled = false
game.StarterGui.TimerGUI.Enabled = true
wait(5)
PlayGame(Player, Team)
return Player, Team
elseif Player.TeamColor == game.Teams.Thieves.TeamColor then
game.StarterGui.ChooseTeamGUI.Enabled = false
game.StarterGui.TimerGUI.Enabled = true
wait(5)
PlayGame(Player, Team)
return Player, Team
end
end
--Team Chooser
game.ReplicatedStorage.TeamChooser.OnServerEvent:Connect(function(Player, Team)
local PhysicalTeamColor = Teams:FindFirstChild(Team).TeamColor
Player.TeamColor = PhysicalTeamColor
game.StarterGui.PoliceWinScreen.Enabled = false
game.StarterGui.ThiefWinScreen.Enabled = false
Thieves_Police(Player, Team)
end)
--Gives the Users on the Police Team a Weapon on Spawn
function teamFromColor(color)
for _,t in pairs(game:GetService("Teams"):GetChildren()) do
if t.TeamColor==color then return t end
end
return nil
end
function onSpawned(plr)
local tools = teamFromColor(plr.TeamColor):GetChildren()
for _,c in pairs(tools) do
c:Clone().Parent = plr.Backpack
end
end
function onChanged(prop,plr)
if prop=="Character" then
onSpawned(plr)
end
end
function onAdded(plr)
plr.Changed:connect(function(prop)
onChanged(prop,plr)
end)
end
--Calls the Functions
game.Players.PlayerAdded:connect(onAdded)

You can just wrap the script in a while loop to repeat from the beginning when the round ends. At the end of the loop, right before the end tag, you can reset all the values that are supposed to be reset for the next round.

Related

How to attach rope to player ragdoll and a player (effectively dragging a ragdoll via a rope) without the weird input lag?

I'm first going to start off with my code which is in a Server Script:
local an = Instance.new("Animation")
an.AnimationId = "rbxassetid://11699868187"
local idle = Instance.new("Animation")
idle.AnimationId = "rbxassetid://11699874417"
local ant
local idlet
local canthit = {}
local knockTime = 30
function takeOwnership(model)
for i, v in pairs(model:GetDescendants()) do
if v:IsA("Part") or v:IsA("BasePart") then
repeat
v:SetNetworkOwner(nil)
until v:GetNetworkOwner() == nil
end
end
end
function resetOwernship(model, ply)
for i, v in pairs(model:GetDescendants()) do
if v:IsA("Part") or v:IsA("BasePart") then
v:SetNetworkOwner(ply)
end
end
end
function rag(char)
local ah = Instance.new("IntValue")
ah.Parent = char
ah.Name = "MaxTime"
ah.Value = knockTime
local thib = Instance.new("IntValue")
thib.Parent = char
thib.Name = "Time"
thib.Value = knockTime
for i, v in pairs(char:GetDescendants()) do
if v:IsA("Motor6D") and v.Parent.Name ~= "HumanoidRootPart" then
local Socket = Instance.new("BallSocketConstraint")
local a1 = Instance.new("Attachment")
local a2 = Instance.new("Attachment")
a1.Parent = v.Part0
a2.Parent = v.Part1
Socket.Parent = v.Parent
Socket.Attachment0 = a1
Socket.Attachment1 = a2
a1.CFrame = v.C0
a2.CFrame = v.C1
Socket.LimitsEnabled = true
Socket.TwistLimitsEnabled = true
v:Destroy()
end
end
char.Humanoid.BreakJointsOnDeath = false
char.Humanoid.RequiresNeck = false
end
function unrag(char)
for i,v in pairs(char:GetDescendants()) do
if v:IsA("BallSocketConstraint") then
v.UpperAngle = 0
v.TwistUpperAngle = 0
v.TwistLowerAngle = 0
local Joints = Instance.new("Motor6D",v.Parent)
Joints.Part0 = v.Attachment0.Parent
Joints.Part1 = v.Attachment1.Parent
Joints.C0 = v.Attachment0.CFrame
Joints.C1 = v.Attachment1.CFrame
v:Destroy()
end
end
end
game:GetService("ReplicatedStorage").Jump.OnServerEvent:Connect(function(ply)
if ply.Character and ply.Team == game:GetService("Teams").Survivor then
if ply.Character.Ragdoll.Value == true then
--game:GetService("ReplicatedStorage"):WaitForChild("Message"):FireClient(ply, "Sorry, jumping isn't available for ragdolls right now")
end
end
end)
game.Players.PlayerAdded:Connect(function(p)
if #game:GetService("Teams").Beast:GetPlayers() == 1 then
p.Team = game:GetService("Teams").Survivor
else
p.Team = game:GetService("Teams").Beast
end
p.CharacterAdded:Connect(function(c)
canthit[p] = nil
if p.Team == game:GetService("Teams").Beast then
local theBat = game:GetService("ServerStorage").Bat:Clone()
theBat.Parent = c
theBat.Equipped:Connect(function()
local h = c:FindFirstChild("Humanoid")
if h then
local a = h:FindFirstChild("Animator")
if a then
idlet = a:LoadAnimation(idle)
idlet:Play()
end
end
end)
theBat.Activated:Connect(function()
local h = c:FindFirstChild("Humanoid")
if h then
local a = h:FindFirstChild("Animator")
if a then
ant = a:LoadAnimation(an)
ant:Play()
theBat.Handle.Swoosh:Play()
local thinge = theBat.Handle.Touched:Connect(function(t)
local ply = game.Players:GetPlayerFromCharacter(t:FindFirstAncestorWhichIsA("Model"))
local ragd = ply.Character:FindFirstChild("Ragdoll")
if ragd then
if ragd.Value == true then
return
end
end
if ply and ply.Team == game:GetService("Teams").Survivor and ply ~= p and not canthit[ply] then
theBat.Handle.Hit:Play()
canthit[ply] = true
local char = ply.Character
ragd.Value = true
rag(char)
while not (char.Time.Value <= 0) do
takeOwnership(char)
char.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
wait(1)
char.Time.Value -= 1
char.HP.Value -= .5
end
if char.HP.Value <= 0 then
char.HP.Value = 0
game:GetService("ReplicatedStorage"):WaitForChild("Message"):FireAllClients(ply.Name.." has been captured!")
char.Humanoid.Health = 0
return
end
char.Time:Destroy()
char.MaxTime:Destroy()
char.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
unrag(char)
resetOwernship(char, ply)
ragd.Value = false
coroutine.wrap(function()
wait(5)
canthit[ply] = nil
end)()
end
end)
wait(.2)
thinge:Disconnect()
end
end
end)
theBat.Unequipped:Connect(function()
if idlet then
idlet:Stop()
end
end)
end
end)
end)
So, this is my horrible code for a little game I am making. It's kind of similar to Flee the Facility. In my game, the person who is the 'beast' should be able to drag a player when they are knocked out, but they can't. I tried adding a rope constraint to the ragdoll and the 'beast', but it just makes the beast have input lag and makes it's animations go weird.
I must note that the beast is a random player. I would try setting ownership of the ragdoll'd player to the grabber (which is the 'beast') but I need to set it to the server in order to change the state to Physics. I would use an event and a local script but I do not want this to be exploitable at all.
So, my question is: How do I attach a rope from a player to a ragdolled player without the non-ragdolled player lagging or having weird input lag and weird animations?
Like I said, I tried setting ownership but that wouldn't work as I need server ownership for setting the humanoid's state to physics. Just using takeOwnership() then ChangeState both on the same line wouldn't work so I had to put it in the while loop.

How to a team system ? (Roblox)

im trying to make a tag game that one player from the spectate team or nutural team will be chosen to be the tag and another will be chosen to be the runner. They'll both teleport to a small map, there the tag will have to try catch the runner before the times up.
Now my problem is that when the player loads to the game he does'nt autoassigned to the nuturalteam(spectateteam) and also when the players tp to the map they wont change the teams to a tager and runner they'll both be in the same team. Help will be appriciated!
Also i dont get any errors in the outpot besides "loadstring is not availble".
Here is the round system script:
Teams = game:GetService("Teams")
local SpectateTeam = game.Teams.Spectate
local ItTeam = game.Teams.It
local RunnerTeam = game.Teams.Runner
local roundlength = 5
local intermissionLength = 4
local inRound = game.ReplicatedStorage.InRound
local Status = game.ReplicatedStorage.Status
local LobbySpawn = workspace.Map.SpawnLobby
local MapSpawnIt = workspace.Map.SpawnMapIt
local MapSpawnRunner = workspace.Map.SpawnMapRunner
local frame = game.StarterGui.ScreenGuimenu.Frame
local KillerSpawn = workspace.Map.SpawnMapIt
local lobbyspace = workspace.Lobbyspace
game.Players.PlayerAdded:Connect(function(player)
player.Team = SpectateTeam
end)
inRound.Changed:Connect(function(player)
if inRound.Value == true then
local chosen = Players:GetChildren()[math.random(1, #Players:GetChildren())]
print(" is It")
chosen.Team = ItTeam
local runner = SpectateTeam:GetPlayers()[math.random(1, #Players:GetChildren())]
print(" is Runner")
runner.Team = Teams.Runner
wait()
runner.Character.HumanoidRootPart.CFrame = MapSpawnRunner.CFrame
chosen.Character.HumanoidRootPart.CFrame = KillerSpawn.CFrame
end
if inRound.Value == false then
for _, player in pairs(game.Players:GetChildren(player)) do
local char = player.Character
char.HumanoidRootPart.CFrame = LobbySpawn.CFrame
player.Team = SpectateTeam
end
end
end)
local function RoundTimer()
while wait() do
for i = intermissionLength, 0, -1 do
inRound.Value = false
wait(1)
Status.Value = "Intermission:" .. i .."seconds left!"
end
for i = roundlength, 0, -1 do
inRound.Value = true
wait(1)
Status.Value = "Game:" .. i .."seconds left!"
end
end
end
spawn(RoundTimer) ```
I found the answer! i just forgot to sync the color of the teams with the spawns :)

Not giving output When running LocalScript inside of StarterGui

So, Im tring to make a Mind Control script inside of Roblox. Im using the local script so i can use the UserInputServer Module. But When I Run It(Its inside of StartGui), I doesn't give any output. Here is the source:
--Made By BioShot!--
local UIS = game:GetService("UserInputService")
local Enabled = false
local Active = false
game.Players.PlayerAdded:Connect(function(plr)
print("Player Added!")
UIS.InputBegan:Connect(function(input)
if(input['KeyCode'] == Enum['KeyCode']["E"]) then
if(Enabled == true) then
--Rase Player/Dummy/NPC
local Mouse = plr:GetMouse()
Active = true
while(Active == true) do
local Enemy = Mouse["Target"]
print(Enemy)
Enemy.CFrame = Enemy.CFrame + CFrame.new(0,1,0)
wait(0.5)
end
else
--Drop Player/Dummy/NPC
end
end
end)
UIS.InputEnded:Connect(function(input)
if(input['KeyCode'] == Enum["KeyCode"]["F"]) then
Enabled = true
print("Enabled.")
end
if(input['KeyCode'] == Enum["KeyCode"]["E"]) then
Active = false
end
end)
end)
The statements are only printed after game.Players.PlayerAdded:Connect(function(plr) detects a player being added. Due to the code running in a LocalScript, the player will have already been added by the time the script starts waiting for players. If a second player joins the game, "Player Added!" will indeed be printed in the first player's console.
The player can instead be indexed by using local plr = game:GetService("Players").LocalPlayer.
The script still errors when the player's mouse is pointing to nothing and when trying to change the Enemy's position, but these can be easily fixed. The script then lifts objects upwards by hovering over them and pressing E.
Final code:
--Made By BioShot!--
local UIS = game:GetService("UserInputService")
local Enabled = false
local Active = false
local plr = game:GetService("Players").LocalPlayer
print("Player Added!")
UIS.InputBegan:Connect(function(input)
if(input['KeyCode'] == Enum['KeyCode']["E"]) then
if(Enabled == true) then
--Rase Player/Dummy/NPC
local Mouse = plr:GetMouse()
Active = true
while(Active == true) do
local Enemy = Mouse["Target"]
if Enemy then --Make sure the player's mouse isn't pointing to nothing
print(Enemy)
Enemy.CFrame += Vector3.new(0,1,0)
end
task.wait(0.5) --More accurate than wait(0.5)
end
else
--Drop Player/Dummy/NPC
end
end
end)
UIS.InputEnded:Connect(function(input)
if(input['KeyCode'] == Enum["KeyCode"]["F"]) then
Enabled = true
print("Enabled.")
end
if(input['KeyCode'] == Enum["KeyCode"]["E"]) then
Active = false
end
end)

Why do I keep getting the error "attempt to index nil with 'Cash' in my script?

For a bit of context, I'm making a Tycoon on Roblox to test my knowledge in lua. Everything was working fine until I tried making leaderstats. The first script, which is what makes the Tycoon
function, is here:
local TycoonInfo = script.Parent:WaitForChild("TycoonInfo")
local OwnerValue = TycoonInfo:WaitForChild("Owner")
local Buttons = script.Parent:WaitForChild("Buttons")
local Purchases = script.Parent:WaitForChild("Purchases")
local Objects = {}
function validateHitByOwner(Hit)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value== Player then
return true
end
end
return false
end
for i,v in pairs(Buttons:GetChildren()) do
local Object = Purchases:FindFirstChild(v.Object.Value)
if Object then
Objects[Object.Name] = Object:Clone()
Object:Destroy()
if v:FindFirstChild("Dependency") then
coroutine.resume(coroutine.create(function()
v.Button.Transparency = 1
v.Button.BillboardGui.Enabled = false
v.Button.CanCollide = false
if Purchases:WaitForChild(v.Dependency.Value,90000) then
v.Button.Transparency = 0
v.Button.CanCollide = true
v.Button.BillboardGui.Enabled = true
end
end))
end
local DB = false
v.Button.Touched:Connect(function(Hit)
if validateHitByOwner(Hit)then
if DB == false then
DB = true
if v.Button.Transparency == 0 then
local Purchased = DoPurchase(Hit,v,v.Price.Value,Objects[v.Object.Value])
if Purchased then
warn("Purchased")
else
warn("Can't purchase")
end
end
DB = false
end
end
end)
end
end
function DoPurchase(Hit,Button,Cost,Object)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value == Player then
local name = game.Players:GetChildren()
local CashValue = game.Players.name.leaderstats.Cash -- Error here
if CashValue then
if CashValue.Value >= Cost then
CashValue.Value = CashValue.Value - Cost
Object.Parent = Purchases
Button:Destroy()
return true
end
end
end
end
return false
end
The next script, which makes the leaderboard and assigns a player that has recently joined to a random available Tycoon, is here:
function FindEmptyTycoon()
for i,v in pairs(workspace.Tycoons:GetChildren()) do
if v.TycoonInfo.Owner.Value == nil then
return v
end
end
return nil
end
game.Players.PlayerAdded:Connect(function(Player)
local Tycoon = FindEmptyTycoon()
Tycoon.TycoonInfo.Owner.Value = Player
local stats = Instance.new("Folder",Player)
stats.Name = "leaderstats"
local Cash = Instance.new("IntValue",stats)
Cash.Name = "Cash"
end)
And then, the script that is stored in all purchasable items to give the Player money, is here:
function giveCash(player)
wait(3.33)
local Cash = player.leaderstats.Cash
Cash.Value = Cash.Value + 2
end
By the way, these scripts are versions of the original scripts that I've been trying to edit so they can actually work, and I think I've been getting close to fixing the errors. The original scripts can be found here (in order of appearance):
local TycoonInfo = script.Parent:WaitForChild("TycoonInfo")
local OwnerValue = TycoonInfo:WaitForChild("Owner")
local Buttons = script.Parent:WaitForChild("Buttons")
local Purchases = script.Parent:WaitForChild("Purchases")
local Objects = {}
function validateHitByOwner(Hit)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value== Player then
return true
end
end
return false
end
for i,v in pairs(Buttons:GetChildren()) do
local Object = Purchases:FindFirstChild(v.Object.Value)
if Object then
Objects[Object.Name] = Object:Clone()
Object:Destroy()
if v:FindFirstChild("Dependency") then
coroutine.resume(coroutine.create(function()
v.Button.Transparency = 1
v.Button.BillboardGui.Enabled = false
v.Button.CanCollide = false
if Purchases:WaitForChild(v.Dependency.Value,90000) then
v.Button.Transparency = 0
v.Button.CanCollide = true
v.Button.BillboardGui.Enabled = true
end
end))
end
local DB = false
v.Button.Touched:Connect(function(Hit)
if validateHitByOwner(Hit)then
if DB == false then
DB = true
if v.Button.Transparency == 0 then
local Purchased = DoPurchase(Hit,v,v.Price.Value,Objects[v.Object.Value])
if Purchased then
warn("Purchased")
else
warn("Can't purchase")
end
end
DB = false
end
end
end)
end
end
function DoPurchase(Hit,Button,Cost,Object)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value == Player then
local CashValue = game.ServerStorage.PlayerCash:FindFirstChild(Player.Name)
if CashValue then
if CashValue.Value >= Cost then
CashValue.Value = CashValue.Value - Cost
Object.Parent = Purchases
Button:Destroy()
return true
end
end
end
end
return false
end
function FindEmptyTycoon()
for i,v in pairs(workspace.Tycoons:GetChildren()) do
if v.TycoonInfo.Owner.Value == nil then
return v
end
end
return nil
end
game.Players.PlayerAdded:Connect(function(Player)
local Tycoon = FindEmptyTycoon()
Tycoon.TycoonInfo.Owner.Value = Player
local stats = Instance.new("BoolValue",Player)
stats.Name = "leaderstats"
stats.Parent = game.ServerStorage
local Cash = Instance.new("IntValue",stats)
Cash.Name = Player.Name
Cash.Value = 0
Cash.Parent = game.ServerStorage.PlayerCash
end)
local amount = 2
local timedelay = 2.33
local currencyname = "Cash"
wait(1)
while true do
wait(timedelay)
for i,v in pairs(game.ServerStorage.PlayerCash:GetChildren()) do
if v:FindFirstChild("leaderstats") and v then
v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount
end
end
end
local name = game.Players:GetChildren()
Why do you store the list of Players's children in a variable called name? This function returns a table. name would be more suitable for a string.
local CashValue = game.Players.name.leaderstats.Cash -- Error here
game.Players is https://developer.roblox.com/en-us/api-reference/class/Players
I cannot make sense of game.Players.name and even less of game.Players.name.leaderstats
Did you mean Player.leaderstats?
I would expect an error message for Players.name.leaderstats before facing an error for game.Players.name.leaderstats.Cash
name is not a Property of Players so you should not be allowed to index Players.name
I'm no Roblox expert but from what I see your code is so off that you really should start with simple tutorials rather than with fixing this code.
I think you should start over and make sure you understand how Instance.new is used properly and such things.
Using better variable names will also help.

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