Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Weird distortion on RayCast renderer, anyone know how to fix it?

Asked by 2 years ago

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!

Answer this question