Use variable outside of remote event

Okay, so. I’m trying to write an attack system that activates upon a player using a tool. The thing is, since there’s only one part, I have to clone it, but identifying them is… tricky between two scripts.

Here’s my code:

In localscript inside of tool:

local cooldown = false
local tool = script.Parent
local toolName = tool.Name
local Player = game:GetService("Players").LocalPlayer
local model = "AttackModel"
local modelname = model.. Player.Name
local Mouse = Player:GetMouse()
local remEvent = game.ReplicatedStorage.Attack

script.Parent.Activated:connect(function()
	if not cooldown then
		remEvent:FireServer(Mouse.Hit.Position, modelname)
		cooldown = true
		for i = 5, 0, -1 do
			wait(1)
			tool.Name = " (Cooldown: " .. i .. ")"
		end
		cooldown = false
		tool.Name = toolName
	end
end)

Inside Animation server script: (This part works, I’m just including it so you can see what the name should be like)

local part = game.ReplicatedStorage.AttackModel
local model = part:Clone()
model.Parent = game.Workspace
local TweenService = game:GetService("TweenService")
local remEvent = game.ReplicatedStorage.Attack

local MidRange = -10
local EndRange = 240

remEvent.OnServerEvent:connect(function(player, aim, modelname)
	local name = model.Name
	model.Name = modelname
	print(model.Name)
	local frame = CFrame.lookAt(player.Character.HumanoidRootPart.CFrame.Position, aim)
	print(aim)
	local pos = frame
	print(pos)
	local dir = pos.LookVector
	print(dir)
	local EndPos = pos + (dir * EndRange)
	print(EndPos)
	local MidPos = pos + (dir * MidRange)
	print(MidPos)
	model:PivotTo(pos)
	TweenService:Create(model.Primary, TweenInfo.new(1, Enum.EasingStyle.Linear), {["CFrame"] = MidPos}):Play()
	wait(1)
	TweenService:Create(model.Primary, TweenInfo.new(1, Enum.EasingStyle.Linear), {["CFrame"] = EndPos}):Play()
	wait(1)
	TweenService:Create(model.Primary, TweenInfo.new(1, Enum.EasingStyle.Linear), {["CFrame"] = EndPos}):Cancel()
	model:PivotTo(CFrame.new(0,0,0))
end)

Inside the Damage script (This is the one I’m having trouble with)

local remEvent = game.ReplicatedStorage.Attack

local name = ""
local model
remEvent.OnServerEvent:connect(function(player, aim, modelname)
	name = modelname
	model = game.Workspace:WaitForChild(name)
	print("Name:".. name)
end)

model.LeftHitbox.Touched:Connect(function(hit) --// Part Touched!
	if game.Players:GetPlayerFromCharacter(hit.Parent) then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		player.Character.Humanoid.Health -= 1
	end
end)

model.RightHitbox.Touched:Connect(function(hit) --// Part Touched!
	if game.Players:GetPlayerFromCharacter(hit.Parent) then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		player.Character.Humanoid.Health -= 1
	end
end)

When I print the modelname in the Animation script, it turns out as “AttackModelPlayerName” (I’m using placeholders for names), as it should. However, for some reason, in the Damage script, even though I defined the variable before the remote event, it runs before the remove event fires and still thinks the value is nil when it gets to the .Touched methods, so it sees it as a syntax error or something and won’t run again when the name is correct.

If you need any more info, please tell me.

Thank you for answering!

I would suggest using Spatial Query for this as it helps a lot more with hitboxes, but this isn’t what you want.

Before we start, here are some questions:

  1. Is .Touched running before the RemoteEvent?

  2. Have you tried to use a separate script and BindableEvents?

Please answer these questions for more information about your issue, and as a possible solution, I would recommend using BindableEvents:

-- your damage script
local BindableEvent = ReplicatedStorage.BindableEvent -- Wherever it is;

remEvent.OnServerEvent:connect(function(player, aim, modelname) -- your remote event
	BindableEvent:Fire(modelname);
end)
-- separate server script for handling the BindableEvent

local BindableEvent = ReplicatedStorage.BindableEvent -- Wherever it is;

BindableEvent.Event:Connect(function(modelname)
	local model = game.Workspace:WaitForChild(name);
	
	-- your .Touched code
	model.LeftHitbox.Touched:Connect(function(hit) --// Part Touched!
		if game.Players:GetPlayerFromCharacter(hit.Parent) then
			local player = game.Players:GetPlayerFromCharacter(hit.Parent)
			player.Character.Humanoid.Health -= 1
		end
	end)

	model.RightHitbox.Touched:Connect(function(hit) --// Part Touched!
		if game.Players:GetPlayerFromCharacter(hit.Parent) then
			local player = game.Players:GetPlayerFromCharacter(hit.Parent)
			player.Character.Humanoid.Health -= 1
		end
	end)
end)

Try this and see if it helps. If it doesn’t, I highly recommend Spatial Query.

Well, .Touched runs whenever the player touches the hitbox of one of the parts of the attack (It’s like throwing two knives side by side, so I used two hitboxes instead of one extra wide one for more accuracy), and the RemoteEvent should run whenever the tool is used, so, RemoteEvent should run before the .Touched

No, I have not tried using bindable events because I’m relatively new to Roblox scripting and don’t really know what those are. But, I’ll try your solution

1 Like

Oh, and, the error is attempt to index nil with 'LeftHitbox', in case you were wondering

This worked, thank you very much. I may have to start learning bindable events

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.