-
What do you want to achieve? Keep it simple and clear!
I want to create a path for a raycast so the bullets can damage humanoids without glitching due to the physics engine. -
What is the issue? Include screenshots / videos if possible!
I have the script create a raycast but for some reason it goes in a straight line. -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I’ll be honest that it is my first time attempting anything with raycasting, I have been looking on the forums for anything that could possibly help me figure it out, but most solutions were FastCast which I don’t want to use, or others were too vague for me to understand.
I am using ApplyImpulse() for the bullets but I want to use the raycasts to get accurate collision, here is part of the script:
local BulletPos = BulletPart.Position
local Direction = (Pos - BulletPos).Unit
local Force = (Direction * BulletXYZForce.Value) + Vector3.new(0, BulletYForce.Value, 0)
local Bullet = BulletPart:Clone()
Bullet.Parent = workspace.Debris
Bullet.Position = BulletPos
Bullet:ApplyImpulse(Force * Bullet.AssemblyMass)
local raycast = workspace:Raycast(BulletPos, Direction)
if raycast then
task.wait(raycast.Distance/(BulletXYZForce.Value + BulletYForce.Value))
local tempbullet = Instance.new("Part")
tempbullet.Anchored = true
tempbullet.CanCollide = false
tempbullet.Parent = workspace.Debris
tempbullet.Size = Vector3.new(0.1,0.1,0.1)
tempbullet.Position = raycast.Position
Bullet:Destroy()
print(raycast.Instance)
if raycast.Instance.Parent:FindFirstChild("Humanoid") then
--do thingy here
end
return
end
if u want to use “custom” physics for projectiles rather than relying on roblox’s physics, i think you should try the following, assuming you’re using RunService and are doing this on every frame:
- see if the projectile’s lifetime has expired. if yes, stop everything.
- calculate how far the projectile should travel (multiply the “delta time” *and “desired speed” of the projectilr).
- perform a raycast in the direction of travel.
now, if this raycast hits something:
- then disconnect the connection (maybe even destroy a cosmetic bullet that visualized said projectile.)
BUT… if the raycast hits nothing:
- update the projectile’s position and direction.
- move a cosmetic object to match the new position if desired.
EDIT: use a “gravity” parameter to pull it downward and as the gravity changes the velocity, the direction should be recalculated.
Okay so the physics stuff with the cosmetic bullet works fine as I’m using ApplyImpulse() but I’m mainly having trouble with raycasting. I’m not to sure how I should get the raycast to have the same trajectory, basically like some games where you’d need to shoot slightly above a npc or player to hit them. Also to specify I’m not using RunService currently. If you could show me some sort of example that would helpful to show me what I should be doing here.
personally i just leave the cosmetic bullet anchored and just set the position to the current position of the projectile, and as for an example, this is the main raycast function from a module that i’ve written:
connection = RunService.Heartbeat:Connect(function(deltaTime)
if tick() - initialTime > config.lifetime then
connection:Disconnect()
if cosmeticObject then
cosmeticObject:Destroy()
end
return
end
local travelDistance = velocity * deltaTime
local rayDirection = currentDirection * travelDistance
local result
if config.radius then
result = workspace:Spherecast(currentPosition, config.radius, rayDirection, config.raycastParams)
else
result = workspace:Raycast(currentPosition, rayDirection, config.raycastParams)
end
if result then
if config.onHit then
config.onHit(result)
end
connection:Disconnect()
if cosmeticObject then
cosmeticObject:Destroy()
end
else
local newPosition, velocityVector = updatePosition(deltaTime)
currentPosition = newPosition
if cosmeticObject then
cosmeticObject.Position = currentPosition
cosmeticObject.CFrame = CFrame.lookAt(currentPosition, currentPosition + velocityVector)
end
end
end)
the configuration table looks like this:
projectile:Cast(config: {
start: Vector3,
direction: Vector3,
speed: number, -- studs per second
lifetime: number,
gravity: number,
hasCosmetic: boolean,
cosmeticTemplate: Instance?, -- cosmetic 'projectile' that follows the path of the real one
raycastParams: RaycastParams,
radius: number?, -- if provided, performs spherecast (improves game feel)
onHit: (RaycastResult?) -> () -- callback for custom behavior (i.e. damage and stuff)
})
Okay this is kind of confusing but I will try to figure this out. I’ll let you know if I get some of it working