So right now im making a C4 throwing system for my game civilized but the ray keeps casting down (vid below) https://streamable.com/l7yojh
heres my script
local C4 = script.Parent.C4
local config = script.Parent.Config
local Vel = config.Drop.Value
local Drop = config.Vel.Value
local beam1
function findcollisions(Root, Torso, up)
local table1 = {Root, Torso, up}
for i,v in pairs(game.Workspace:GetDescendants()) do
if v:IsA("BasePart") then
if v.CanCollide == false then
table.insert(table1, v)
end
end
end
print(table1)
return table1
end
script.Parent.Throw.OnServerEvent:Connect(function(player, Pos)
local clone = script.Parent.C4:Clone()
clone.Parent = workspace
print(Pos)
print("Sarting")
local head = player.Character.Head
print((Pos - head.CFrame.p).unit + Vector3.new(90,0,0))
local ignore = findcollisions(player.Character.HumanoidRootPart, player.Character.UpperTorso, player.Character.LowerTorso)
local shotVel = {}
shotVel[1] = Vel
local drop = {}
drop[1] = Drop
local mousehit = Pos
local hole = head
local ray = Ray.new(head.CFrame.p, (head.Position - Pos).unit * shotVel[1])
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray,ignore)
local oldpos = position
if hit == nil then
repeat
print("Continueing")
shotVel[1] = (shotVel[1] - .05)
drop[1] = (drop[1] + .1)
local ray = Ray.new(oldpos, (oldpos - mousehit).unit * shotVel[1] + Vector3.new(0,-drop[1],0))
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray,ignore)
beam1 = Instance.new("Part", workspace)
beam1.BrickColor = BrickColor.new("Cyan")
beam1.FormFactor = "Custom"
beam1.Material = "Neon"
beam1.Transparency = 0.25
beam1.Anchored = true
beam1.Locked = true
beam1.CanCollide = false
local distance = (oldpos - position).magnitude
beam1.Size = Vector3.new(0.3, 0.3, distance)
beam1.CFrame = CFrame.new(oldpos, position) * CFrame.new(0, 0, -distance / 2)
oldpos = position
clone.Position = oldpos
print(hit.Name)
until
hit ~= nil
else
print("Hit")
local clone = C4:Clone()
clone.Parent = workspace
clone.CFrame = CFrame.new(position, position + normal)
end
end)
ive tried to fix this by using head.CFrame.lookvector but that gives the same results.
please help thanks in advance!
This probably doesn’t have anything to do with your problem, but I’d like to point out that we’re not supposed to use Ray.new anymore.
We should be using workspace:Raycast()
You are taking a unit direction vector and multiplying it by a magnitude (as you should), but then adding on a separate vector for drop. Instead change the direction, get the unit, and multiply it by speed. Or maintain the velocity and change the xyz components each iteration for gravity and drag.
local direction = (endPos - startPos)
local velocity = direction*speed
repeat
velocity = Vector3.new(velocity.X*0.95, velocity.Y*0.95 - drop, velocity.Z*0.95)
until hit
You accidently exchanged the declarations here. Since the rays are being cast directly downwards, is config.Drop.Value and in turn Vel 0?
(oldpos - Pos) will be a vector from Pos to oldpos and hence its unit vector will be the opposite direction, unless shotVel[1] oddly happens to be negative.
i tried that and it sort of worked (vid below) but the projectile slows down just before hitting the target https://streamable.com/7teapx
local C4 = script.Parent.C4
local config = script.Parent.Config
local Vel = config.Drop.Value
local Drop = config.Vel.Value
local beam1
function findcollisions(Root, Torso, up)
local table1 = {Root, Torso, up, script.Parent}
for i,v in pairs(game.Workspace:GetDescendants()) do
if v:IsA("BasePart") then
if v.CanCollide == false then
table.insert(table1, v)
end
end
end
return table1
end
script.Parent.Throw.OnServerEvent:Connect(function(player, Pos)
local clone = script.Parent.C4:Clone()
clone.Parent = workspace
print("Sarting")
local head = player.Character.Head
local ignore = findcollisions(player.Character.HumanoidRootPart, player.Character.UpperTorso, player.Character.LowerTorso)
local shotVel = {}
shotVel[1] = Vel
local drop = {}
drop[1] = Drop
local mousehit = Pos
local hole = head
local ray = Ray.new(head.CFrame.p, CFrame.new(head.Position, Pos).LookVector * shotVel[1])
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray,ignore)
local oldpos = position
print(hit)
if hit == nil then
repeat
wait()
shotVel[1] = (shotVel[1] - .05)
drop[1] = (drop[1] + .1)
local direction = (Pos - oldpos)
local velocity = direction*shotVel[1]
velocity = Vector3.new(velocity.X, velocity.Y - drop[1], velocity.Z)
local ray1 = Ray.new(oldpos, velocity * shotVel[1])
local hit1, position1, normal1 = workspace:FindPartOnRayWithIgnoreList(ray1,ignore)
beam1 = Instance.new("Part", workspace)
beam1.BrickColor = BrickColor.new("Cyan")
beam1.FormFactor = "Custom"
beam1.Material = "Neon"
beam1.Transparency = 0.25
beam1.Anchored = true
beam1.Locked = true
beam1.CanCollide = false
local distance = (oldpos - position1).magnitude
beam1.Size = Vector3.new(0.3, 0.3, distance)
beam1.CFrame = CFrame.new(oldpos, position1) * CFrame.new(0, 0, -distance / 2)
beam1:Destroy()
oldpos = position1
clone.Position = oldpos
if hit1 then
print(hit1.Name)
print("FINISHED")
clone:Destroy()
local clone = C4:Clone()
clone.Parent = workspace
clone.CFrame = CFrame.new(position1, position1 + normal1)
end
until
hit1 ~= nil
else
print("Hit")
local clone = C4:Clone()
clone.Parent = workspace
clone.CFrame = CFrame.new(position, position + normal)
end
end)
From a physics perspective, velocity is a direction and speed, direction is a unit vector, and speed is a number. You stated velocity = direction*speed then later multiplied velocity by speed again. Remove the second time you have shotVel[1] (which is speed). local ray1 = Ray.new(oldpos, velocity)
I don’t know if you were trying to make a realistic arc or not. If you do as I suggested, you just have to make sure your units line up. It helps if do this consistently which would also mean knowing the time for each step and adding it to your calculation.
Here is an example of how I would accomplish this.
local speed = 30 --studs per second
local acceleration = Vector3.new(0, -98.1, 0) --studs pre second per second
local timeLimit = 10 --In case the ray is shot into the void
local ignore = Instance.new("Folder", workspace)
function drawBeam(startPos, endPos)
local beam1 = Instance.new("Part")
beam1.BrickColor = BrickColor.new("Cyan")
beam1.FormFactor = "Custom"
beam1.Material = "Neon"
beam1.Transparency = 0.25
beam1.Anchored = true
beam1.Locked = true
beam1.CanCollide = false
local distance = (endPos - startPos).magnitude
beam1.Size = Vector3.new(0.3, 0.3, distance)
beam1.CFrame = CFrame.new(startPos, endPos) * CFrame.new(0, 0, -distance / 2)
beam1.Parent = ignore
end
local rayCastParams = RaycastParams.new()
rayCastParams.FilterType = Enum.RaycastFilterType.Blacklist
rayCastParams.FilterDescendantsInstances = {ignore, }
function throw(startPos, targetPos)
local velocity = (targetPos - startPos).Unit*speed
local lastPosition = startPos
local timePos = 0
local connection
connection = game["Run Service"].Heartbeat:Connect(function(dt)
timePos = timePos + dt
if timePos >= timeLimit then
timePos = timeLimit
connection:Disconnect()
--No parts were hit in the time limit. Place C4 anyway?
end
local newPosition = startPos + velocity*timePos + 0.5*acceleration*timePos^2
drawBeam(lastPosition, newPosition)
local result = workspace:Raycast(lastPosition, (newPosition - lastPosition), rayCastParams)
if result then
connection:Disconnect()
--Plant C4 at result.Position
end
lastPosition = newPosition
end)
end
wait(2)
throw(Vector3.new(0,20,0), Vector3.new(10,20,0))