How to make a part ricochet?

Bullets in my game are parts with body velocity. I’m trying to make it so when a bullet hits a wall it bounces back at an angle like in the picture below.

1 Like

I remember doing this a while back, one of the tutorials that really helped me was this one . You basically just “reflect” the ray.

3 Likes

I created the ray how do I make a part go to the hits???

Are you talking about actually making the ray hit a player?

1 Like

How do I make the bullet follow the path of the ray?

I can’t actually remember how I did it myself, as this was a good while ago. (I haven’t done anything weapon related since)

I found a few things that may be able to help you though,

You can use this to calculate the bullet trajectory, you can just update the bullet position on each frame, like raycasting from one point to another, until you eventually hit something.

I’m sure there is a much better response that my own, if you get a bit too confused however, you can use Fast Cast, which is a very handy model (that happens to have bullet ricocheting too. (Fast Cast Link)

Hope this helps!

1 Like

Thankyou! I figured it out! thanks to your article!!! :heart_eyes:

1 Like

https://streamable.com/efpqc6 How is this even possible???!!!???

How did you make that? I’m still having trouble trying to make the ricochet script, it’s so confusing

I’m trying to change the lookvector to the reflected one but it wont let me

Can you explain a bit more? Now that I understand how it works, i can help with your problem :slight_smile:

nevermind I figured it out but, I’m trying to make the character ricochet but when the character jumps and then activates ricocheting, the character gets kinda buggy and I don’t know how to fix that

hmm… show me your script i can help with ur character being buggy

    char.Humanoid.WalkSpeed = 0
	char.Humanoid.JumpPower = 0
	
	local currentPos = char.HumanoidRootPart.Position
	local currentNormal = char.HumanoidRootPart.CFrame.lookVector
	local curDistance = 0

	local stepDistance = 2 -- speed
	local stepWait = 0 -- wait time between raycasting
	
	local timeSec = 0
	
	coroutine.wrap(function()
		repeat
		if timeSec <= 4 then
			wait(1)
			timeSec = timeSec + 1
		else
			char.Humanoid.WalkSpeed = 16
			char.Humanoid.JumpPower = 50
			timeSec = 69
		end
		until timeSec == 69
	end)()

	local function Step(overrideDistance)

		-- Cast ray:
		local params = RaycastParams.new()
		local direction = currentNormal * (overrideDistance or stepDistance)
		params.FilterType = Enum.RaycastFilterType.Blacklist
		params.FilterDescendantsInstances = {char.HumanoidRootPart}
		local result = workspace:Raycast(currentPos, direction)
		local pos

		if result then
			pos = result.Position
		else
			pos = currentPos + direction
		end

		char.HumanoidRootPart.CFrame = CFrame.new(currentPos:Lerp(pos, 0.5), pos)

		local oldPos = currentPos
		currentPos = pos

		if result then
			-- r = d - 2(d DOT n)n
			-- Reflect:
			d = false
			if d == false then 
				d = true
				local norm = result.Normal
				local reflect = (currentNormal - (2 * currentNormal:Dot(norm) * norm))
				currentNormal = reflect
				char.HumanoidRootPart.Position = pos
				Step(stepDistance - (pos - oldPos).Magnitude)
				return
			end
		end

		curDistance = (curDistance + (pos - oldPos).Magnitude)


		-- Recurse if max distance not reached:
		--	if curDistance < maxDistance then
		if timeSec <= 4 then
			wait(stepWait)
			Step()
		end
	end
	
	Step()

The reason is because the other parts of the character still can collide so it will cause collisions and make the character buggy. Can you show me other scripts too?

what do you mean by other scripts? and i’ll see if cancollide = false works

Edit: It did not really work.

bruh, then idk i will inspect ur script a bit more

instead of using char.HumanoidRootPart.Position = pos, you could do char:MoveTo(pos)

oh true i can try that

30 words