Right now I have the stock Hyperlaser; I'm trying to make the shot, on impact with a surface, change its velocity according to the angle of the shot relative to the surface impact, without changing its velocity.
The simplest example would be how light reflects off a completely reflective surface; that' the effect I'm trying to get here. I've tried tons of different code snippets that reflect in strange and bizarre ways.
How could I do this?
This would be a good use of the Dot Product The dot product, also commonly known as the scalar product, is an operation preformed on vectors and returns a single number.
Example pulled from article:
local tool = script.Parent; -- the Tool local handle = tool:WaitForChild("Handle"); -- does not continue without a Handle! function reflect(input, normal) -- this vector reflector will reflect the laser -- using dot method b/c vector3 return -2 * input:Dot(normal) * normal + input; end; function drawray(ray, parent) -- draws the ray of the laser local part = Instance.new("Part", parent or game.Workspace.CurrentCamera); -- do only you can see the lasers part.FormFactor = Enum.FormFactor.Custom; part.Material = Enum.Material.Neon; -- glowy effect c: part.Size = Vector3.new(.2, ray.Direction.magnitude, .2); part.CFrame = CFrame.new(ray.Origin + ray.Direction/2, ray.Origin + ray.Direction) * CFrame.Angles(math.pi/2,0,0); part.Anchored = true; part.CanCollide = false; part.BrickColor = BrickColor.new("Bright red"); return part; end; function fire(from, to, bounce) -- function that fires the laser local bounce = bounce or 0; if bounce <= 5 then -- how many times can it reflect -- first ray is to calculate distance and normal local ray = Ray.new(from, (to - from).unit * 500); local hit, pos, normal = game.Workspace:FindPartOnRay(ray, tool.Parent); -- this is the actual ray we use and draw local ray2 = Ray.new(from, (pos - from)); local part = drawray(ray2, tool); -- throw out the laser beam later game:GetService("Debris"):AddItem(part, 2); -- calculate the reflected ray local ref = reflect((pos - from), normal); if hit then local hum = hit.Parent:FindFirstChild("Humanoid"); if hum then hum:TakeDamage(math.random(10, 15)); end; -- shoot a ray in the reflected position fire(pos, pos + ref, bounce + 1); end; end end; script.Parent.Equipped:connect(function(mouse) -- connect the function to when the tool is equipped mouse.TargetFilter = game.Workspace; script.Parent.Activated:connect(function() -- whenever the player clicks with the tool out fire(handle.CFrame.p, mouse.Hit.p); -- call the function end); end);