Hello
I was making weapons when I had this problem.
For some reason, the Touched event doesn’t always fire.
Let’s talk about the script:
This script is from the server and uses a third party library to shoot in an arc.
I actually don’t know why I cant upload video in the topic, so here
My guess as to why the event doesn’t fire is the high speed of the part, which is why the server doesn’t have time to process it.
There is script:
Shooted:Connect(function(player: Player, itemId: string, target: Vector3)
local foundItem = Inventory:getItemById(player, itemId)
if not foundItem then
return
end
local projectile = foundItem:WaitForChild("Projectile").Value :: BasePart
local damage = foundItem:GetAttribute("Damage")
local knockback = projectile:GetAttribute("Knockback")
local isExplosion = projectile:GetAttribute("Explosion")
--It's some projectile
local newProjectile = projectile:Clone()
--The main part starts here
newProjectile.Touched:Connect(function(hitPart: BasePart)
if not hitPart or not hitPart.Parent then
return
end
local knockbackPosition = newProjectile.CFrame.LookVector * knockback
local character = hitPart:FindFirstAncestorOfClass("Model")
local targetPlayer = game.Players:GetPlayerFromCharacter(character)
if targetPlayer == player then
print("Owner hit")
return
end
print("Hitted")
--In fact, what comes next does not really matter,
--because the execution does not even get to here.
if isExplosion then
_explosion(newProjectile.Position)
local nearestCharacters =
_findNearestCharacters(newProjectile.Position, 10)
--For debugging
print(nearestCharacters)
for i, character in ipairs(nearestCharacters) do
character.Humanoid.Health -= damage
character:TranslateBy(knockbackPosition)
end
local nearestPlayers = _findNearestPlayers(newProjectile.Position, 4)
for i, targetPlayer in ipairs(nearestPlayers) do
if targetPlayer == player then
continue
end
local health = PlayerStats:getPlayerStat(targetPlayer, PlayerStats.Stats.Health)
health.Value -= damage
local character = targetPlayer.Character
if not character then
continue
end
end
newProjectile:Destroy()
return
end
if not isExplosion and not targetPlayer and character then
character.Humanoid.Health -= damage
character:TranslateBy(knockbackPosition)
elseif not isExplosion and targetPlayer then
local health = PlayerStats:getPlayerStat(targetPlayer, PlayerStats.Stats.Health)
character:TranslateBy(knockbackPosition)
health.Value -= damage
end
if foundItem.Name == "Egg" then
local part = Instance.new("Part")
part.Anchored = true
part.CastShadow = false
part.Size = Vector3.new(3, 3, 3)
part.Color = Color3.fromRGB(85, 170, 0)
part.Position = newProjectile.Position
part.Parent = workspace
end
if not character and not targetPlayer then
newProjectile:Destroy()
return
end
newProjectile:Destroy()
end)
newProjectile.Parent = workspace
--Launch a projectile
--RANGED_WEAPON_LAUNCH_SPEED = 500
ProjectileLib.LaunchProjectile(newProjectile, foundItem.Handle.Position, target, Constants.RANGED_WEAPON_LAUNCH_SPEED)
Debris:AddItem(newProjectile, PROJECTILE_MAX_LIFETIME)
end)
There’s function “_findNearestCharacters”
local function _findNearestCharacters(position: Vector3, radius: number)
local result = {}
for i, character in ipairs(workspace.Game.NPC:GetChildren()) do
if character.Humanoid.Health <= 0 then
continue
end
local humanoidRootPartPosition = character.HumanoidRootPart.Position
local distance = (humanoidRootPartPosition - position).Magnitude
if distance > radius then
continue
end
table.insert(result, character)
end
return result
end
Any help appreciated
Thanks!