Tree Generates floating and on the bottom of the terrain

image
image
image

RAYCAST:

local Map = Table[1]
	local CheckHeight = Table[2]

	local MapX = Map[1]
	local MapZ = Map[2]

	local RandX = math.random() * MapX - MapX / 2
	local RandZ = math.random() * MapZ - MapZ / 2

	local Origin = Vector3.new(RandX, CheckHeight, RandZ)
	local Direction = Vector3.new(0,-1,0) * 1000
	local Result = workspace:Raycast(Origin, Direction, Params)
	
	return Result, {RandX, RandZ}

MAIN

coroutine.wrap(function()
				if Result and Result.Instance:IsA("Terrain") then
					GENERATION:GenerateModel({Model, Result.Position + NewVector3})
				end
			end)()

GENERATION:

local Model : Model = Table[1]:Clone()
	
	local Position = Table[2]
	
	local NewCFrame
	if typeof(Position) == "Vector3" then
		NewCFrame = CFrame.new(Position)
	else
		NewCFrame = CFrame.new(Vector3.new(Position[1], Position[2], Position[3]))
	end
	
	Model:ScaleTo(math.floor(math.random(1, 1.5)))
	
	Model:PivotTo(NewCFrame)
1 Like

NewVector3 is the yoffset. Like some of the models clip through the ground without it.

2 Likes

Have you tried using :MoveTo? It may be easier to use than raycasts. This functionality may be important for you:

You could try making the Y position really low and :MoveTo will automatically adjust it higher.

Example GENERATION code:

local Model : Model = Table[1]:Clone()

local Position = Table[2]
Position = typeof(Position) == "Vector3" and Vector3.new(Position.X, -100, Position.Z)
	or Vector3.new(Position[1], -100, Position[3])

Model:ScaleTo(math.floor(math.random(1, 1.5)))

Model:MoveTo(Position)

Unrelated but this will always return 1, may not be intended:

1 Like

This is what happened.

image

It just stops setting the position of it.

1 Like

Sorry, you should revert to your old code. I just realized what you did wrong.

You’re adding the .Position value of the raycast to your current position, when you should be setting the .Position.Y to your current position’s Y value.

Main code:

coroutine.wrap(function()
	if Result and Result.Instance:IsA("Terrain") then
		NewVector3 = Vector3.new(NewVector3.X, Result.Position.Y, NewVector3.Z)
		GENERATION:GenerateModel({Model, NewVector3})
	end
end)()

The YOffset is named “NewVector3”

this is what it did.

image

Also I’m not sure if the model is not in-game because when i check explorer, the cloned tree’s children is gone. The meshes are anchored.

image
image

1 Like

Ohhh, sorry I didn’t know that. Could you show your whole code? I’m confused on where you get the randomly generated position.

1 Like

This is slow and inefficient. Do not recommend this.

1 Like

Is it actually slower though? If you could show me some benchmarks I would appreciate it.

1 Like

It is hundreds times slower than raycasting.

1 Like
local Result = RAYCAST:GetCast({{STATUS.MapX, STATUS.MapY}, STATUS.CheckHeight})
			
			local M_F : Folder

			local Success, Fail = pcall(function()
				M_F = STATUS[ARGS[1]]
			end)

			local Model = M_F:GetChildren()[math.random(1, #M_F:GetChildren())]
			
			local ARGS = string.split(M_F.Name, "_")
			local NewVector3 = STATUS[ARGS[1].."_YOffset"]
			
			coroutine.wrap(function()
				if Result and Result.Instance:IsA("Terrain") then
					local Model = GENERATION:GenerateModel({Model, Result.Position})
					repeat
						task.wait()
					until #Model:GetChildren() > 1
				end
				
			end)()
			
			task.wait()
2 Likes

I think you accidentally did STATUS.MapY instead of STATUS.MapZ.

Code:

local Result = RAYCAST:GetCast({{STATUS.MapX, STATUS.MapZ}, STATUS.CheckHeight})
			
local M_F : Folder

local Success, Fail = pcall(function()
	M_F = STATUS[ARGS[1]]
end)

local Model = M_F:GetChildren()[math.random(1, #M_F:GetChildren())]
	
local ARGS = string.split(M_F.Name, "_")
local NewVector3 = STATUS[ARGS[1].."_YOffset"]
	
coroutine.wrap(function()
	if Result and Result.Instance:IsA("Terrain") then
		local Model = GENERATION:GenerateModel({Model, Result.Position})
		repeat
			task.wait()
		until #Model:GetChildren() > 1
	end
	
end)()
	
task.wait()

(Not sure what status is though, just inferring because I don’t have the full script)

2 Likes

It still functions the same since MapY is MapZ and I forgot to rename the variable.

3 Likes

Status is the settings.

3 Likes

Are there any errors? Coroutine.wrap blocks all errors from logging, so just replace it with task.spawn and tell me if there are any errors.

2 Likes

There’s no errors. But there’s errors from HD admin that might’ve interfered with the script.

2 Likes

One thing I’m wondering about is how you get the :GetCast values. In your code, it shows that you returned 2 things for :GetCast, but you only used 1 variable to hold them. Could you check to see if that’s interfering with anything?

1 Like

I’ve changed that already. It shouldn’t be an issue.

1 Like

Could you show me your updated code? Just want to make sure I don’t go over old issues.

1 Like
function RAYCAST:GetCast(Table)

	local Map = Table[1]
	local CheckHeight = Table[2]

	local MapX = Map[1]
	local MapZ = Map[2]

	local RandX = math.random() * MapX - MapX / 2
	local RandZ = math.random() * MapZ - MapZ / 2

	local Origin = Vector3.new(RandX, CheckHeight, RandZ)
	local Direction = Vector3.new(0,-1,0) * CheckHeight
	local Result = workspace:Raycast(Origin, Direction, Params)
	
	return Result
end

1 Like