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.
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)
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.
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.
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.
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.