Hello! I am currently working on a light simulation game that has absorbers, reflecters, infractors and even logic gates. The absorbers and mostly the reflectors have been done, but I got a problem.
As you can see, not all of the light particles are deflected. I have 2 scripts in my game that control all the light particles.
Reflection Detector & Manager
local LightFolder = game.Workspace.SimulationParts.LightParticles
local GlobalLightProperties = require(game.ReplicatedStorage.LightPropertySet)
local RunService = game:GetService("RunService")
local NameIgnoreList = {"Light","Laser"}
local ParentIgnoreList = {"BaseParts","TheBox"}
local SubT1 = {Instance=nil,Distance=nil,Normal=nil}
function SimLightFol(LightF:{})
local LightSpeed = GlobalLightProperties.LightSpeed
local RefreshTime = GlobalLightProperties.RefreshTime
local DetectionDistance = GlobalLightProperties.DectectionDistance
local LifeTime = GlobalLightProperties.LifeTime
local ol_params = OverlapParams.new()
ol_params.FilterType = Enum.RaycastFilterType.Blacklist
ol_params.FilterDescendantsInstances = {game.Workspace.BaseParts}
local PNB = workspace:GetPartsInPart(game.Workspace.BaseParts.TheBox.Ref,ol_params)
for order, Light in pairs(LightF) do
if not table.find(PNB,Light) then
Light:Destroy()
end
local PartsInLight = workspace:GetPartsInPart(Light)
if PartsInLight then
for _, part in pairs(PartsInLight) do
if not table.find(NameIgnoreList,part.Name) then
local Rot = Light.Orientation
Light.Orientation = Rot-(Vector3.new(180,180,180))
end
end
end
local rayOrigin = Light.Position
local rayDirection = Light.CFrame.RightVector*180
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {LightFolder:GetChildren()}
local rayR = workspace:Raycast(rayOrigin,rayDirection,rayParams)
local InLightDet = workspace:GetPartsInPart(Light)[1]
if rayR or (((InLightDet~=nil)and (not table.find(NameIgnoreList,InLightDet))) and InLightDet.ClassName=="Part")then
if not table.find(NameIgnoreList,((rayR or SubT1).Instance or InLightDet).Name) then
local Dis = (rayR or SubT1).Distance or (InLightDet.Position-Light.Position).Magnitude
local Ins = (rayR or SubT1).Instance or InLightDet
local Rot = Light.Orientation
local RNorm = (rayR or SubT1).Normal
local Norm = (RNorm or InLightDet.Orientation/45)*90
if Dis <= DetectionDistance then
local RotX,LightRotationY,RotZ = Rot.X,Rot.Y,Rot.Z
local NormX,NormY,NormZ = Norm.X,Norm.Y,Norm.Z
local RotNorm = Rot+Norm
Light.Orientation = Rot+Norm-(Vector3.new(180,180,180)-Rot)
end
end
end
end
end
while task.wait() do
SimLightFol(LightFolder:GetChildren())
end
Light Movement Manager
local LightFolder = game.Workspace.SimulationParts.LightParticles
local GlobalLightProperties = require(game.ReplicatedStorage.LightPropertySet)
local TweenService = game:GetService("TweenService")
local NameIgnoreList = {"Light,Laser"}
local RunService = game:GetService("RunService")
function CFPS(s)
local a = {(workspace:GetRealPhysicsFPS()/60),(60/workspace:GetRealPhysicsFPS())}
return a[s]
end
function SimLightFol(LightF)
local LightSpeed = GlobalLightProperties.LightSpeed
local RefreshTime = GlobalLightProperties.RefreshTime
local DetectionDistance = GlobalLightProperties.DectectionDistance
local LifeTime = GlobalLightProperties.LifeTime
for order, Light in pairs(LightF) do
local Tween = TweenService:Create(Light,TweenInfo.new((RefreshTime*1.2*CFPS(2)/2), Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {CFrame = (Light.CFrame+(Light.CFrame.RightVector*(LightSpeed*RefreshTime*CFPS(1)/2)/1.2))*CFrame.Angles(0,0,0)})
Tween:Play()
end
end
while true do
wait(GlobalLightProperties.RefreshTime*CFPS(2)*1.2)
if #LightFolder:GetChildren() > 0 then
SimLightFol(LightFolder:GetChildren())
end
end
Extra Info:
- The light particle’s speed is based on the physic fps.
- Light Particles outside of the box are automaticly deleted.
- FPS averages at about 30-40,
- Plans are made to add NOT, OR, XOR and AND gates that would work with light particles entering and exiting instead of values like 0 or 1. Not yet sure how to implement it but that is far from my priority right now.