Touched doesn't always fire when tweening

I’m trying to make a rock firing effect.
Basically a tool and when you activatie it, it will fire a rock from your character to your mouse position.

I use Tween service for this to move the rock.
But when i fire the rock, the touch event will fire instantly and do damage while the rock hasn’t reached his goal yet.
And sometimes it doesn’t do damage.

I also added a explotion when the rock reached his goal.
So i added a ball that’s gonna grow but it also does nothing.
In this case, the touch event will only fire when a instance is moving in the explotion.

Can you help me please?

1 Like

Would you be able to provide the script in question?

1 Like

I am currently on my phone but i will try,

script.Parent.FiredEvent.OnServerEvent:Connect(function(Player, MousePosition)
local Rock = game.ReplicatedStorage.Rock:Clone()
Rock.Parent = workspace
Rock.Position = Player.Character["Right Arm"]
local Tween = TweenService:Create(rock,TweenInfo.New{0.5,lineair,out},{Position = MousePosition}
Tween:Play()
Rock.Touched:Connect(function(Hit)
if humanoïde then
Hit Parent.Humanoid:TakeDamage(15)
end
end)
Tween.Completed:Connect(function()
local Boom = game.ReplicatedStorage.Boom:Clone()
local Tween = TweenService:Create(boom,TweenInfo.New{0.5,lineair,out},{Size = Vector3.new(20,20,20)}
Tween:Play()
Boom.Touched:Connect(function(Hit)
if humanoïde then
Hit.Parent.Humanoid:TakeDamage(15)
end
end)
end)
end)
1 Like
Rock.Touched:Connect(function(Hit)
	if Hit.Parent:FindFirstChild("Humanoid") then
		Hit.Parent.Humanoid:TakeDamage(15)
	end
end)

Basically you just needed to add a conditional check to make sure the BasePart instance the Rock is hitting belongs to something which contains a Humanoid instance then you can deal the necessary damage to that Humanoid.

1 Like

Yeah i added that in my script but i’ve forgotten to add it in my copy.

1 Like
script.Parent.FiredEvent.OnServerEvent:Connect(function(Player, MousePosition)
	local Char = Player.Character
	local Hum = Char.Humanoid
Rock.Touched:Connect(function(Hit)
	local Humanoid = Hit.Parent:FindFirstChild("Humanoid") 
	if Humanoid then
		if Humanoid ~= Hum then
			Humanoid:TakeDamage(15)
		end
	end
end)

Try adding both of these parts, it’ll prevent the Rock from damaging the player who fired it/threw it.

It still doesn’t work when i tried that.

I imagine the problem is because you’re setting the Position/CFrame of the rock. Touched uses physics, so if you aren’t moving the object with physics it doesn’t work very well. I’d recommend using :GetTouchingParts with a RunService.Heartbeat connection or moving the rock with physics (you can make it non-collide and add a body force (that cancels gravity) to make it fly in a straight line).

For the second solution, basically:

  • Create the rock (make sure it’s non-collide)
  • Create a BodyForce
  • Add the BodyForce to the rock, set the force to Vector3.up * massOfRock * Workspace.Gravity
  • Set the velocity of the rock to the direction and speed you want it to travel.
  • Wait for the time you want it to travel
  • Do the effects and stuff (explosion, etc)
1 Like

First of all I wouldn’t use TweenService to move the Rock around the world. I would rather use BodyVelocity instead.

Secondly, while the Touched event does work, it’s inconsistent. So instead, I would recommend you use Region3 (which I will be using) or :GetTouchingParts(), as those will give you much better results. Note that the following code should be inside a Server Script and not a Local Script.

The code for the Rockthrowing should look something like this:

local Event = game:GetService("ReplicatedStorage").FireEvent


Event.OnServerEvent:Connect(function(Player,MousePosition)

     --Getting the Player's Character.
     local Character = Player.Character or Player.CharacterAdded:Wait()
     
     --Simply a clone from the actual 
     local Rock = game:GetService("ReplicatedStorage").Rock:Clone()

     --Create a BodyVelocity Instance.
     local BodyVelocity = Instance.new("BodyVelocity")

     --Set the direction of the Rock. You can change the 100 to the speed you would want.
     BodyVelocity.Velocity = (MousePosition - Character.HumanoidRootPart.Position).Unit * 100

     --Place the Rock at the Player's position
     Rock.CFrame = Character.HumanoidRootPart.CFrame

     BodyVelocity.Parent = Rock
     Rock.Parent = game:GetService("Workspace")
     --Self explanatory^


     local Count = 0 --Keep this at 0.
     
     --Change the 100 to how long you want the Rock to be on the screen. 100  is about 4 seconds.
     while Count < 100 do

          wait()
          Count = Count + 1

          --Getting the Region of the Part.
          local Region = Region3.new(Rock.Position - Rock.Size/2, Rock.Position + Rock.Size/2) 

          --Go through all the parts inside the Region.
          for _,PartInRegion in pairs(workspace:FindPartsInRegion3(Region)) do
               
               --Check if it's a Player, or at least something that has a Humanoid
               if PartInRegion.Parent:FindFirstChild("Humanoid") then

                    if PartInRegion.Parent.Name ~=  Player.Name then

                         --Damage the Player.
                         PartInRegion.Parent.Humanoid:TakeDamage(15)
                    end
               end
          end
     end
end

--Destroy the Rock after the while loop, so that it doesn't stay on the workspace forever :)
Rock:Destroy()

Now this isn’t the best answer, as you hit the Player multiple times because there’s no debounce, but I’m sure you’ll be capable of figuring this one out. This type of script would be perfectly fit for a ModuleScript too.

Hope I could have helped!

1 Like