Now, I'm not great at geometry (never have been) but one thing I understand is raycasting. So, as a test, I decided to make a Wolfenstein-3d style raycasting renderer in Roblox, just for fun. I've got a lot of it working; including a basic camera, screen drawing (unfortunately done with frames because Roblox) and a simple raycasting setup with resolution and FOV settings. It's in one big script, including player creation, raycasting, and all that. Just run the code inside a ScreenGui.
The problem I'm having is a distortion issue on there (not the lens distortion, what I mean becomes apparent when you test it out) wherein the geometry of the raycaster doesn't seem to match with the geometry of the world. Parts clip in and out of existence, everything is stretched and distorted, and more. Like I said, I'm no good at geometry and angles, so this isn't really stuff I'm great at. Could anyone help?
Here's the full code, run it in a LocalScript under a ScreenGui.
local RES = 4 local FOV = 70 local movespeed = 50 local player = Instance.new("Part") player.Anchored = true player.Position = Vector3.new(0,10,0) player.Size = Vector3.new(2,1,2) player.Parent = workspace local camera = workspace.CurrentCamera local UIS = game:GetService("UserInputService") UIS.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition game.Players.LocalPlayer.CameraMaxZoomDistance = 0.5 game.Players.LocalPlayer.CameraMode = Enum.CameraMode.LockFirstPerson game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart").Anchored = true game.Players.LocalPlayer.Character.HumanoidRootPart.Position = Vector3.new(0,-20,0) local function singleray(x, offset, ogdir) local ray = workspace:Raycast(player.Position, (player.CFrame.LookVector + CFrame.Angles(0, math.rad(offset), 0).LookVector) * 512) local dist local actdist local colormod local saturation if ray then actdist = (ray.Position - player.Position).Magnitude if ray.Material == Enum.Material.Marble then colormod = 0.65 saturation = 1 else colormod = 0 saturation = 0 end else actdist = 512 dist = 512 colormod = 0.65 saturation = 0.25 end local frame = Instance.new("Frame") frame.AnchorPoint = Vector2.new(0,0.5) frame.Position = UDim2.new(0, x, 0.5, 0) frame.Size = UDim2.new(0, RES, 0, camera.ViewportSize.Y*8/actdist) frame.BorderSizePixel = 0 frame.BackgroundColor3 = Color3.fromHSV(colormod, saturation, 1) frame.Parent = script.Parent end local function raycast() for _,v in pairs(script.Parent:GetChildren()) do if v:IsA("Frame") then v:Destroy() end end local ogdir = player.Orientation.Y local offset = FOV/2 local x = 0 local sl = camera.ViewportSize.X/RES for i = 1, sl do singleray(x, offset, ogdir) offset -= FOV/sl x += RES end end game:GetService("RunService").RenderStepped:Connect(function(dt) raycast() player.Orientation += Vector3.new(0,-UIS:GetMouseDelta().X,0) if UIS:IsKeyDown(Enum.KeyCode.W) then player.CFrame = player.CFrame + (player.CFrame.LookVector * movespeed * dt) end if UIS:IsKeyDown(Enum.KeyCode.S) then player.CFrame = player.CFrame + (player.CFrame.LookVector * -movespeed * dt) end if UIS:IsKeyDown(Enum.KeyCode.A) then player.CFrame = player.CFrame + ((player.CFrame * CFrame.Angles(0, math.pi/2, 0)).lookVector * movespeed * dt) end if UIS:IsKeyDown(Enum.KeyCode.D) then player.CFrame = player.CFrame + ((player.CFrame * CFrame.Angles(0, math.pi/2, 0)).lookVector * -movespeed * dt) end camera.CFrame = player.CFrame end)
Thanks in advance!