Adjusting bounce angle

I want to make a script that can make rays have a customizable reflection angle. ex:

here is my current test code

local startCFrame  = script.Parent.CFrame -- Where we derive our position & normal
local normal = startCFrame.lookVector
local position = startCFrame.p
local ray = Ray.new(position, normal * 500)
local hit3, position3, surfaceNormal3 = game.Workspace:FindPartOnRay(ray) -- Cast ray

local Dist = (position-position3).magnitude
local Lazer = Instance.new("Part")
Lazer.BrickColor = BrickColor.new("Really red")
Lazer.Material = "Neon"
Lazer.Parent = game.Workspace
Lazer.Transparency = 0.5
Lazer.Anchored = true
Lazer.CanCollide = false
Lazer.Size = Vector3.new(0.1,0.1,Dist)
Lazer.CastShadow = false
Lazer.CFrame = CFrame.new(position,position3)*CFrame.new(0,0,-Dist/2)
Lazer.Name = "Lazer"

local OrientCFrame = CFrame.new(position, surfaceNormal3)

-- actual part being rotated below!!!
local Clone = game.Lighting.EpicFart:Clone()
Clone.Parent = game.Workspace
print(surfaceNormal3)
Clone.CFrame = CFrame.new(position3, startCFrame.LookVector) --* CFrame.Angles(math.rad(0), 0, 0)
--Clone.CFrame = CFrame.lookAt(Clone.Position, Clone.Position + surfaceNormal3)
Clone.CFrame = Clone.CFrame * CFrame.new(0, 0, 0)

I have tried a few things already but I dont really know how to do it.

1 Like

You may want to look at this article by Sleitnick

Hope this helps!

To bounce something properly you want to reflect something. This formula is as follows:

norm = norm.unit
surfaceNorm = surfaceNorm.unit -- TODO: Make sure these aren't magnitude 0 before doing .unit otherwise we get infinite values (unlikely)
local reflected = norm- 2*(norm:Dot(surfaceNorm))*surfaceNorm
local value = reflected*speed*0.5 -- takes 50% of the original velocity and assume we lost some in the bounce

Note all input vectors are normalized (.unit). You’ll need the raycast surface .Normal, and then you can scale the reflected result by the magnitude.

3 Likes