Let’s say I have a function called ABC(), and ABC() will return a value after it is called. But the time to return the value is unknown, it can be 3 seconds, it can be 5 seconds, it can be X seconds. Therefore, is there a method that can stop the code and wait until the value is returned?
local function ABC()
--xxx
task.wait(X) --X in a unknown
return sth
end
local ReturnedValue = ABC() --How to stop the code here until the value is returned
HungryManRemoteFunction.OnServerInvoke = function(plr, skillName, rushDuration)
if(skillName == "DeadlyEat") then
if(not DeadlyEatProcessing) then
--Defind basic items
local LocalPlayer = plr
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character.Humanoid
local Animator = Humanoid.Animator
local HRP = Character.HumanoidRootPart
local hitCharacter = CombatModuleScript.CreateHitbox(Vector3.new(3, 5, 3), HRP.CFrame * CFrame.new(0, -1, -3), {Character}, true, Character, rushDuration)
if(#hitCharacter == 0 or hitCharacter == nil) then return false end
DeadlyEatProcessing = true
task.spawn(function() DeadlyEatAnim(Character, hitCharacter) end)
return true
end
end
end
function CombatModule.CreateHitbox(size, cframe, ignore, weld, char, second)
if weld == nil then weld = false end
local hitbox = Instance.new("Part", workspace.Fx)
hitbox.Size = size
hitbox.CFrame = cframe
hitbox.CanCollide = false
hitbox.Anchored = true
hitbox.Transparency = 0.5
local damageCharacter = {}
if(not weld) then
for _, hit in pairs(workspace:GetPartsInPart(hitbox)) do
if(hit.Parent:FindFirstChild("Humanoid") and table.find(ignore, hit.Parent) == nil and table.find(damageCharacter, hit.Parent) == nil) then
table.insert(damageCharacter, hit.Parent)
end
end
hitbox:Destroy()
return damageCharacter
elseif(weld) then
local WeldConstraint = Instance.new("WeldConstraint", hitbox)
WeldConstraint.Part0 = hitbox
WeldConstraint.Part1 = char.HumanoidRootPart
local connection
connection = hitbox.Touched:Connect(function(hit)
if(hit.Parent:FindFirstChild("Humanoid") and table.find(ignore, hit.Parent) == nil) then
connection:Disconnect()
hitbox:Destroy()
return {hit.Parent}
end
task.delay(second, function()
connection:Disconnect()
if(hitbox) then
hitbox:Destroy()
end
return {}
end)
end)
end
end
No, it didn’t. After I call the function CombatModuleScript.CreateHitbox(), it return a nil and this is the error code ServerScriptService.CharacterServerScripts.HungryManServerScript:85: attempt to get length of a nil value
Well your wrapping it in a connection and using task.delay which will mean it doesn’t yield, instead you would need to do a repeat until the hitcharacter variable doesn’t equal nil
I am not very understand, can you give a example using my code? What do you mean with the hit variable, how can I get the hit variable without using hitbox.Touched:Connect(function() xxx end)
Have you tried using a Repeat Until loop? This is just a guess but you could possibly just do a check on the returned function variable until it’s not nil?
The basic idea:
function example1()
local number = 5
print("waiting 3 seconds")
task.wait(3)
return number -- when called, returns the number 3
end
function example2()
repeat -- keeps trying to run example1 until it ACTUALLY returns (until it's not nil)
result = example1() -- use a global variable or else this will not work
task.wait()
until result
warn(result) -- doesn't give an error since we're stuck in the repeat loop until the 'result' variable is NOT nil
-- run the rest of your code here since there are no errors!
end
example2()
How does this work?
When the example2 function is called, it instantly runs a Repeat Loop that makes sure that the returned function actually has a value and is not nil, after it has confirmed that it does indeed have a value it breaks out of the Repeat Loop and continues with the rest of the code.
I solved using @hya123456h method already but still tysm!
function CombatModule.CreateHitbox(size, cframe, ignore, weld, char, second)
if weld == nil then weld = false end
local hitbox = Instance.new("Part", workspace.Fx)
hitbox.Name = "hitbox"
hitbox.Size = size
hitbox.CFrame = cframe
hitbox.CanCollide = false
hitbox.Transparency = 0.5
local damageCharacter = {}
if(not weld) then
hitbox.Anchored = true
for _, hit in pairs(workspace:GetPartsInPart(hitbox)) do
if(hit.Parent:FindFirstChild("Humanoid") and table.find(ignore, hit.Parent) == nil and table.find(damageCharacter, hit.Parent) == nil) then
table.insert(damageCharacter, hit.Parent)
end
end
hitbox:Destroy()
return damageCharacter
elseif(weld) then
hitbox.Anchored = false
local WeldConstraint = Instance.new("WeldConstraint", hitbox)
WeldConstraint.Part0 = hitbox
WeldConstraint.Part1 = char.HumanoidRootPart
local connection
local returnValue = 0
connection = hitbox.Touched:Connect(function(hit)
if(hit.Parent:FindFirstChild("Humanoid") and table.find(ignore, hit.Parent) == nil) then
connection:Disconnect()
hitbox:Destroy()
returnValue = {hit.Parent}
end
task.delay(second, function()
connection:Disconnect()
if(hitbox) then
hitbox:Destroy()
end
returnValue = {}
end)
end)
repeat task.wait() until returnValue ~= 0
return returnValue
end
end
this is my new hitbox function, I changed the return method and fixed