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!
