if i want to make a non-hitscan projectile and have it accurately register when it hits someone, what should i use
projectile.Touched:Connect(function(partWhichItHit)
print("hit")
end)
most big games (even outside of roblox) use a system that moves the projectile and detect collisions in the same ‘update tick’ (usually a RunService.Heartbeat
) which will makes sure the projectile will not pass through a target without detecting it
sample code:
local pos = starting point
projectile.Parent = workspace
projectile.PrimaryPart.Anchored = true
projectile.PrimaryPart.CanCollide = false
local velocity = CFrame.new(pos, target position).lookVector * speed
while true do
local hb = game:GetService("RunService").Heartbeat:Wait()
local nextpos = pos + (velocity * hb)
projectile:SetPrimaryPartCFrame(CFrame.new(pos, nextpos))
local ray = Ray.new(pos, nextpos - pos)
local hit = workspace:FindPartOnRayWithIgnoreList(ray, ignore list)
if hit then
if hit.Parent and game.Players:GetPlayerFromCharacter(hit.Parent) then
print("collided with a player character")
projectile:Destroy()
return
else
print("collided with a non-character object")
projectile:Destroy()
return
end
else
pos = nextpos
--velocity -= Vector3.new(0,workspace.Gravity * hb,0) --//for a gravity-affected arc
4 Likes
If you’re using a high speed projectile this is one method.
You’d want to make a loop that make a raycast to the position before and the position after.
It should look something like this.
local OldPos = PartSpecified.Position
game:GetService("RunService").RenderStepped:Connect(function()
local NewPos = PartSpecified.Position
local RayCast = Ray.new(OldPos, (NewPos - OldPos))
local Part, Position = workspace:FindPartOnRayWithIgnoreList(RayCast, {IgnoredParts})
if (Part) then
--- This is the part that was in between the two render positions
end
end)
You could also use this module called fastcast.
2 Likes