Hi, I’m making a punch script using region3 but when you click to punch, region3 only appears for a split second and then disappears. How can I make the region3 be there when the punch hits?
local Enabled = true
local Combo = 1
wait(.001)
script.Parent.OnServerEvent:connect(function(Player, Action)
local c = Player.Character
if Enabled == false then return end
if Action == "Combat" then
Enabled = false
if Combo == 1 then
Combo = 2
local Anim1 = c.Humanoid:LoadAnimation(script.Punch1)
Anim1:Play()
script.Event:Fire()
elseif Combo == 2 then
Combo = 1
local Anim2 = c.Humanoid:LoadAnimation(script.Punch2)
Anim2:Play()
script.Event:Fire()
end
wait(.2)
local Region = Region3.new(c.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p - Vector3.new(2,2,2),c.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p + Vector3.new(2,2,2)) -- region3
local RTable = workspace:FindPartsInRegion3(Region, nil, 20)
for i,v in pairs(RTable) do
if v.Parent:findFirstChild("Humanoid") and v.Parent:findFirstChild("Deb") == nil and v.Parent ~= c then
v.Parent.Humanoid:TakeDamage(4)
local Deb = Instance.new("BoolValue", v.Parent)
Deb.Name = "Deb"
game.Debris:AddItem(Deb,0.2)
local S = Instance.new("Sound", v)
S.SoundId = "rbxassetid://131237241"
S.PlaybackSpeed = math.random(80,120)/100
S:Play()
local FX = Instance.new("Part", workspace.FX)
FX.Name = "CombatHit"
FX.Transparency = 0
FX.CanCollide = false
FX.Anchored = true
FX.Material = "ForceField"
FX.Color = Color3.new(1,0,0)
FX.Size = Vector3.new(1,1,1)
local SM = Instance.new("SpecialMesh", FX)SM.MeshType = "Sphere"
SM.Scale = Vector3.new(0,0,0)
FX.CFrame = v.Parent.HumanoidRootPart.CFrame*CFrame.new(math.random(-20,20)/10,math.random(-20,20)/10,math.random(-20,20)/10)
local BV = Instance.new("BodyVelocity", v)
BV.maxForce = Vector3.new(25000,25000,25000)
BV.Velocity = c.HumanoidRootPart.CFrame.lookVector*5
game.Debris:AddItem(BV,0.2)
end
end
wait(0.15)
Enabled = true
if script.Parent.Parent.Parent.Humanoid.Health < 1 then
script.Parent.Parent:Destroy()
end
end
end)
You could run a separate thread for the duration of the animation that is being played. You may have to change your logic a bit for hit detection or whatever result you’re trying to achieve. But the thread will fire the Region3 check for the duration of the animation at approximately 1/60th of a second. (How fast RunService.Stepped is fired)
It also won’t yield your code.
local RunService = game:GetService("RunService")
script.Parent.OnServerEvent:connect(function(Player, Action)
local c = Player.Character
if Enabled == false then return end
if Action == "Combat" then
local Anim = nil -- Define the animation variable here
Enabled = false
if Combo == 1 then
Combo = 2
Anim = c.Humanoid:LoadAnimation(script.Punch1)
Anim:Play()
script.Event:Fire()
elseif Combo == 2 then
Combo = 1
Anim = c.Humanoid:LoadAnimation(script.Punch2)
Anim:Play()
script.Event:Fire()
end
wait(.2)
coroutine.resume(coroutine.create(function()
while Anim.IsPlaying() and RunService.Stepped:wait() do -- While the animation is playing and we wait for the next frame (Approx. 1/60th a second)
local Region = Region3.new(c.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p - Vector3.new(2,2,2),c.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p + Vector3.new(2,2,2)) -- region3
local RTable = workspace:FindPartsInRegion3(Region, nil, 20)
end))
end)
Alternatively, you could run the same loop at the bottom of the OnServerEvent without a thread. When Region3 returns a part, you can fire a BindeableEvent which can take arguments and handle code whenever a condition is triggered.
You’re going to have to reposition a few variables and rework a bit of the logic. I also did not test the code. But the logic should be straight forward.
local Enabled = true
local Combo = 1
local RunService = game:GetService("RunService")
local Region
local RTable
script.Parent.OnServerEvent:connect(function(Player, Action)
local c = Player.Character
if Enabled == false then return end
if Action == "Combat" then
local Anim1 = c.Humanoid:LoadAnimation(script.Punch1)
local Anim2 = c.Humanoid:LoadAnimation(script.Punch2)
Enabled = false
if Combo == 1 then
Combo = 2
Anim1:Play()
script.Event:Fire()
elseif Combo == 2 then
Combo = 1
Anim2:Play()
script.Event:Fire()
end
wait(.25)
coroutine.resume(coroutine.create(function()
while Anim1.IsPlaying or Anim2.IsPlaying and RunService.Stepped:wait() do -- While the animation is playing and we wait for the next frame (Approx. 1/60th a second)
wait(.01)
Region = Region3.new(c.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p - Vector3.new(2,2,2),c.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p + Vector3.new(2,2,2)) -- region3 -- region3
RTable = workspace:FindPartsInRegion3(Region, nil, 20)
end
for i,v in pairs(RTable) do
RTable = false
Region = false
if v.Parent:findFirstChild("Humanoid") and v.Parent:findFirstChild("Deb") == nil and v.Parent ~= c then
v.Parent.Humanoid:TakeDamage(4)
local Deb = Instance.new("BoolValue", v.Parent)
Deb.Name = "Deb"
game.Debris:AddItem(Deb,0.2)
local S = Instance.new("Sound", v)
S.SoundId = "rbxassetid://131237241"
S.PlaybackSpeed = math.random(80,120)/100
S:Play()
local FX = Instance.new("Part", workspace.FX)
FX.Name = "CombatHit"
FX.Transparency = 0
FX.CanCollide = false
FX.Anchored = true
FX.Material = "ForceField"
FX.Color = Color3.new(1,0,0)
FX.Size = Vector3.new(1,1,1)
local SM = Instance.new("SpecialMesh", FX)SM.MeshType = "Sphere"
SM.Scale = Vector3.new(0,0,0)
FX.CFrame = v.Parent.HumanoidRootPart.CFrame*CFrame.new(math.random(-20,20)/10,math.random(-20,20)/10,math.random(-20,20)/10)
local BV = Instance.new("BodyVelocity", v)
BV.maxForce = Vector3.new(25000,25000,25000)
BV.Velocity = c.HumanoidRootPart.CFrame.lookVector*5
game.Debris:AddItem(BV,0.2)
end
end
end))
wait(0.25)
Enabled = true
if script.Parent.Parent.Parent.Humanoid.Health < 1 then
script.Parent.Parent:Destroy()
end
end
end)
Well your while loop lasts as long as the animation. But what if I hit an enemy on the first frame of the animation and miss them on the last? You’ll overwrite RTable with the empty one.
If you want to achieve a one hit only effect, check if the RTable contains a part with a Humanoid under its parent. If it does, break the loop. (Make sure that if there is a Humanoid under the same parent, it’s not the player’s own)
Hi I was reading this thread and I got the same issue as you when doing what Exeplex said to, I read his solution but I don’t understand how it worked for you. Do you mind helping me?