#Raycast not working

1 messages · Page 1 of 1 (latest)

ember otter
#

I have a system the places trees on terrain, the raycast is used so that the trees stay leveled on the terrain. However "Data" is always nil.

--More Code
local TreeNoise = math.noise(x * 0.01, Seed, z * 0.01)
                        if math.abs(TreeNoise) >= 0.2 and GetClosest(Vector3Position, TreePositions) > 40 then
                            local TreeRaycastPos = Vector3.new(Vector3Position.X, Vector3Position.Y + 100, Vector3Position.Z)
                            local Data = workspace:Raycast(TreeRaycastPos, Vector3.new(0, -1000, 0), NewRaycastParams)
                            print(Data)
                            if Data then
                                table.insert(TreePositions, Data.Position)

                                local NewTree = Tree:Clone()
                                NewTree:PivotTo(CFrame.new(Data.Position))
                                NewTree.Parent = workspace.Trees
                                print("Tree")
                            end

                        end
wispy tendon
#

ah

#

terrain

#

that's your issue

#

are you using parts as terrain?

#

or roblox's built in terrain

#

because if I remember, you can't raycast on terrain..

#

or maybe I'm crazy

#

ahh.. nvm

#

it does work on terrain

#

what's on your raycast parameters?

ember otter
# wispy tendon it does work on terrain

Yes, I am using terrain.
This is my parameters:

local NewRaycastParams = RaycastParams.new()
NewRaycastParams.FilterType = Enum.RaycastFilterType.Exclude
NewRaycastParams.FilterDescendantsInstances = {workspace.Trees:GetChildren()}
wispy tendon
#

so

#

it is.

#

printing Data

#

the variable

#

however it returns nil

#

meaning that it hits..

#

but it doesn't return any values.

#

uh could you try a quick fix?

#

place a part

#

a long one

#

near an area

#

just above the terrain but below the origin of the raycasts

#

then try and see if trees appear

#

sorry if it sounds stupid but just try it

#

what is the tree raycast position anyways?

ember otter
#

Its not detecting the terrain

#

I have no idea

#

I used the part and it detected the part, but not the terrain

wispy tendon
#

shoot

#

now you're going to have to change your terrain generation system/map 💀

ember otter
wispy tendon
#

can you recall anything you changed over the last time?

torpid cape
ember otter
ember otter
#

Bump

torpid cape
#

ye not the source of the problem i dont think, but it doesn't help to have other errors in it

ember otter
#

(It will be used to get s2 btw)

torpid cape
#

ye you would need to send more code

#

most likely your position and/or direction is wrong

#

tbh instead of placing a tree if the raycast hits, you could probably spawn a debug part to visualize the ray

#

that will give you more information on this

torpid cape
#

oh you are generating the terrain at the same time as placement of the trees

torpid cape
#

are any trees being placed at all?

ember otter
#

Data is nil, so no

torpid cape
#

grid snapping formulate is incorrect local Vector3Position = Vector3.new(x * BlockScale, NoiseTrrain * BlockScale, z * BlockScale)

#

GetClosest(Vector3Position, TreePositions) this should be a different function

ember otter
ember otter
#

Like different name?

torpid cape
#

this appears to be perfectly aligned on the corner of a terrain cell lua local TreeRaycastPos = Vector3.new(Vector3Position.X, Vector3Position.Y + 100, Vector3Position.Z) local Data = workspace:Raycast(TreeRaycastPos, Vector3.new(0, -1000, 0), NewRaycastParams)

#

i suggest TreeRaycastPos += Vector3.new(BlockScale,BlockScale,BlockScale)*0.5 so it is in the center of a cell instead of precisely on the corner

torpid cape
#

and your noise range is -6 to 6

torpid cape
# ember otter Different how?

different as in breaks immediately when it finds a tree too close instead of continuing to search for closest tree as this loop could be in the 100's

#

spatial partitioning is a good idea too but mehhhhhh

torpid cape
# ember otter (It will be used to get s2 btw)

almost definitely not getting s2 with this because you have all the generation functions nested in one massive function and terrain gen is a very good candidate for parallel processing which you aren't using

#

often the de-facto first example use-case for actors

#

why pass that up?

torpid cape
#

this is going to create multiple connections in a very, very bad way ```lua

BuildFunction.OnServerEvent:Connect(function(Player : Player, Position : Vector3, Mat : Enum.Material)
    Terrain:FillBlock(Position, BlockSize, Mat)
    if Mat == Enum.Material.Air then
        Mat = 0
    else
        Mat = 1
    end
    
    table.insert(NewDataStore.Value[tostring(Player.UserId)][tostring(SeedGlobal)], {{Position.X, Position.Y, Position.Z}, Mat}) --Save world change
    print(NewDataStore.Value)
end)
```
ember otter
torpid cape
#

so will this ```lua
AxeFunction.OnServerEvent:Connect(function(Player : Player, Tree, TreeRoot : Part)
task.spawn(function()
if TreeRoot then
TreeRoot:Destroy()
task.wait(2)
Tree:Destroy()

        end
    end)
    table.insert()
end)```
torpid cape
torpid cape
#

maybe behind a 10% chance or something so you don't get a visual on every terrain cell, ooor only when data is nil

ember otter
#

But ya ill keep that in mind

ember otter
torpid cape
#

task.spawn makes it async, but parallel is different

#

e.g you can have a parallel async thread just as much as a serial async thread

ember otter
ember otter
torpid cape
#

s2 takes something with interconnectivity usually

#

all you have is a single giant loop that, putting it simply, generates a dull cube

#

you could write for x=1,100 do for z=1,100 do end end and it be almost the same as what you have.

#

also code that is purely algorithmic in nature, which terrain generation is, is not eligible for ranking

#

so

#

y'know make it something useful and decent, make it worthwhile. a mediocre minecraft clone is not going to get you s2

ember otter
ember otter
ember otter
torpid cape
torpid cape
#

that's what actors are for

ember otter
torpid cape
ember otter
torpid cape
#

not exactly...

ember otter
# torpid cape not exactly...

Ok so, I watched a quick video and I think I need to split the generation script into multiple actors. Then tell the scripts what chunk they are generating.

ember otter
# torpid cape not exactly...
local Chunks = 8
    local ChunkSize = WorldSize / Chunks
    local ChunksFinished = 0

    Center = WorldSize / 2
    for ChunkIndex = 1, Chunks do
        local Start = (ChunkIndex - 1) * ChunkSize + 1
        local End = ChunkIndex * ChunkSize
    
        local NewActor = Actor:Clone()
        NewActor:SendMessage("Generation", {Start, End, BlockScale, TrrainThreshhold, WaterEnabled, WorldSize, Seed})
    end
    
#

For every new chuck we clone an actor with the generation script.

torpid cape
#

yep

#

cloning scripts is weird but that's how it's done

ember otter
#

LETS FUCKING GO

torpid cape
#

you also need to connectparallel to the message or task.desync in a regular connect

#

otherwise it will still be running in series

ember otter
# torpid cape yep

Do we also keep a bindable event to track how many chunks are finished?

ChuckFinishedEvent.Event:Connect(function()
        ChunksFinished += 1
        if ChunksFinished == Chunks then
            
        end
    end)
ember otter
#

just in case?

torpid cape
#

there's lots of ways idk if any are better

ember otter
torpid cape
#

each potential solution is equally as best than the last fingerguns

ember otter
# torpid cape yep
Actor:BindToMessageParallel("Generation", function(Message)
    local Start = Message[1]
    local End = Message[2]
    local BlockScale = Message[3]
    local TrrainThreshhold = Message[4]
    local WaterEnabled = Message[5]
    local WorldSize = Message[6]
    local Seed = Message[7]
    
    for z = Start, End do  --Generation
        for x = 1, WorldSize do
            local NoiseTrrain = math.noise(x * 0.1, Seed, z * 0.1) * BlockScale --Prlin Noise, my belovid. Prlin Noise is a math algorithum that tries to create realistic terrain. So far Noise dose this pritty well.
            NoiseTrrain = math.clamp(NoiseTrrain, -6, 6) --Clamps it
            NoiseTrrain = (NoiseTrrain > TrrainThreshhold and TrrainThreshhold or NoiseTrrain) / TrrainThreshhold  --A bunch of math and logic to make the trrain look natral
            NoiseTrrain = (1 - NoiseTrrain)

            local Vector3Position = Vector3.new(x * BlockScale, NoiseTrrain * BlockScale, z * BlockScale) --Creates positions
            local Position = CFrame.new(Vector3Position) 

            local Size = Vector3.new(BlockScale, BlockScale, BlockScale) --Creates the size
            local Material

            if Position.Y >= 17 then --When Rock will generate
                Material = Enum.Material.Rock
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 5, 0), Vector3.new(BlockScale, (BlockScale * 12) - NoiseTrrain, BlockScale), Enum.Material.Ground) --Fills the ground
                
            elseif Position.Y <= 0.5 and WaterEnabled then --When water will generate
                Material = Enum.Material.Water
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 5, 0), Size, Enum.Material.Rock) --Adds rock to the bottom of the water
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 7, 0), Vector3.new(BlockScale, (BlockScale * 12) - NoiseTrrain, BlockScale), Enum.Material.Ground) --Fills the ground

            else
                Material = Enum.Material.Grass
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 5, 0), Vector3.new(BlockScale, (BlockScale * 12) - NoiseTrrain, BlockScale), Enum.Material.Ground) --Fills the ground

                local TreeNoise = math.noise(x * 0.01, Seed, z * 0.01)
                if math.abs(TreeNoise) >= 0.2 and GetClosest(Vector3Position, TreesFolder) > 40 then
                    local TreeRaycastPos = Vector3.new(Vector3Position.X, Vector3Position.Y + 100, Vector3Position.Z)
                    TreeRaycastPos += Vector3.new(BlockScale,BlockScale,BlockScale)*0.5
                    
                    local Data = workspace:Raycast(TreeRaycastPos, Vector3.new(0, -1000, 0), NewRaycastParams)
                    
                    print(Data)
                    if Data then
                        local NewTree = Tree:Clone()
                        NewTree:PivotTo(CFrame.new(Data.Position))
                        NewTree.Parent = workspace.Trees
                        print("Tree")
                    end

                end

            end

            Terrain:FillBlock(Position, Size, Material) --Generate it
        end
    end
    ChuckFinishedEvent:Fire()
end)
#
local Actor = script:GetActor()
local Terrain = game.Workspace:WaitForChild("Terrain")

local TreesFolder = game.Workspace:WaitForChild("Trees")
local Tree = game.Workspace:WaitForChild("Tree")

local ChuckFinishedEvent = game:GetService("ReplicatedStorage"):WaitForChild("ChunkFinished")

local NewRaycastParams = RaycastParams.new()
NewRaycastParams.FilterType = Enum.RaycastFilterType.Exclude
NewRaycastParams.FilterDescendantsInstances = {TreesFolder}
function GetClosest(MainValue : Vector3, Values : {Part})
    local ClosestDistance = math.huge

    for _, v in ipairs(Values) do
        local Distance = (MainValue - v.CFrame.Position).Magnitude
        if Distance < ClosestDistance then
            ClosestDistance = Distance
            
        end
    end
    return ClosestDistance
end
#

Had to split the message.

torpid cape
ember otter
#

I love coding

#

I love coding

#

I love coding

#

I love coding

#

I love coding

torpid cape
#

i may be mistaken on this but if you start with the script disabled then set .enabled=true it will execute immediately

ember otter
torpid cape
#

it needs to be somewhere that scripts will execute

ember otter
#

It gave me an error

#

but still

torpid cape
#

so fix the error

ember otter
torpid cape
#

it took me a while to get a handle on how to work with actors so don't stress if you don't get it immediately

#

this is your first time using them after all

#

so if you clone it you can make the actor set an attribute like IsLoaded and then getattributechangedsignal("IsLoaded"):Wait() is one pattern you could use

ember otter
#

"Not running script because past shutdown deadline"

torpid cape
ember otter
trail iceBOT
#

studio** You are now Level 14! **studio

torpid cape
#

being able to work effectively with actors is an s2 trait among many

#

so may as well get your practice in 🤷

#

i belief you can do it

ember otter
#

alright!

#

but first I go night-night

torpid cape
ember otter
#

cus it is 10 pm

torpid cape
ember otter
#

@torpid cape I'm awake and ready to code! So I worked a little more and I still can't get the script to run. I can't find anything in the docs the mentions this problem.

local Actor = script:GetActor()
local Terrain = game.Workspace:WaitForChild("Terrain")

local TreesFolder = game.Workspace:WaitForChild("Trees")
local Tree = game.Workspace:WaitForChild("Tree")


local NewRaycastParams = RaycastParams.new()
NewRaycastParams.FilterType = Enum.RaycastFilterType.Exclude
NewRaycastParams.FilterDescendantsInstances = {TreesFolder}
function GetClosest(MainValue : Vector3, Values : {Part})
    local ClosestDistance = math.huge

    for _, v in ipairs(Values) do
        local Distance = (MainValue - v.CFrame.Position).Magnitude
        if Distance < ClosestDistance then
            ClosestDistance = Distance
            
        end
    end
    return ClosestDistance
end
#
Actor:BindToMessageParallel("Generation", function(Message)
    task.desynchronize()
    print("Working")

    local Start = Message[1]
    local End = Message[2]
    local BlockScale = Message[3]
    local TrrainThreshhold = Message[4]
    local WaterEnabled = Message[5]
    local WorldSize = Message[6]
    local Seed = Message[7]
    
    for z = Start, End do  --Generation
        for x = 1, WorldSize do
            local NoiseTrrain = math.noise(x * 0.1, Seed, z * 0.1) * BlockScale --Prlin Noise, my belovid. Prlin Noise is a math algorithum that tries to create realistic terrain. So far Noise dose this pritty well.
            NoiseTrrain = math.clamp(NoiseTrrain, -6, 6) --Clamps it
            NoiseTrrain = (NoiseTrrain > TrrainThreshhold and TrrainThreshhold or NoiseTrrain) / TrrainThreshhold  --A bunch of math and logic to make the trrain look natral
            NoiseTrrain = (1 - NoiseTrrain)

            local Vector3Position = Vector3.new(x * BlockScale, NoiseTrrain * BlockScale, z * BlockScale) --Creates positions
            local Position = CFrame.new(Vector3Position) 

            local Size = Vector3.new(BlockScale, BlockScale, BlockScale) --Creates the size
            local Material

            if Position.Y >= 17 then --When Rock will generate
                Material = Enum.Material.Rock
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 5, 0), Vector3.new(BlockScale, (BlockScale * 12) - NoiseTrrain, BlockScale), Enum.Material.Ground) --Fills the ground
                
            elseif Position.Y <= 0.5 and WaterEnabled then --When water will generate
                Material = Enum.Material.Water
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 5, 0), Size, Enum.Material.Rock) --Adds rock to the bottom of the water
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 7, 0), Vector3.new(BlockScale, (BlockScale * 12) - NoiseTrrain, BlockScale), Enum.Material.Ground) --Fills the ground

            else
                Material = Enum.Material.Grass
                Terrain:FillBlock(Position - Vector3.new(0, BlockScale * 5, 0), Vector3.new(BlockScale, (BlockScale * 12) - NoiseTrrain, BlockScale), Enum.Material.Ground) --Fills the ground

                local TreeNoise = math.noise(x * 0.01, Seed, z * 0.01)
                if math.abs(TreeNoise) >= 0.2 and GetClosest(Vector3Position, TreesFolder) > 40 then
                    local TreeRaycastPos = Vector3.new(Vector3Position.X, Vector3Position.Y + 100, Vector3Position.Z)
                    TreeRaycastPos += Vector3.new(BlockScale,BlockScale,BlockScale)*0.5
                    
                    local Data = workspace:Raycast(TreeRaycastPos, Vector3.new(0, -1000, 0), NewRaycastParams)
                    
                    print(Data)
                    if Data then
                        local NewTree = Tree:Clone()
                        NewTree:PivotTo(CFrame.new(Data.Position))
                        NewTree.Parent = workspace.Trees
                        print("Tree")
                    end

                end

            end

            Terrain:FillBlock(Position, Size, Material) --Generate it
        end
    end
    task.synchronize()
    Actor:Destroy()

end)

-# And the trees still don't work

ember otter
#

@torpid cape