如何在 Roblox 中将零件放置在地形之上?

How to place part on top of the terrain in Roblox?

我有一个在我的 ROBLOX 游戏中生成的地形(丘陵、平地、河流),我有一个树模型。树只是一组 "bricks" 所以它看起来有点像 Minecraft 树。

现在我想在 运行 时间以编程方式克隆那棵树,我需要将该副本(克隆)放置在地图上的其他地方。

这一切都很简单。但是在我为我的克隆体设置新坐标后(我保持 Y 轴的坐标与我原来的树相同),它被放置在 或空中,或者在我的地形表面 之下。

如何将它直接放在地形上? 或者如何获取地图上该特定地点的 Y 轴坐标?

谢谢!

编辑

虽然@Kylaaa 的回答非常完整,但我在这里包含了我的解决方案,同时我还需要有关该地方地形(岩石/草地等)material 的信息

function FindTerrainHeight(pos)

local VOXEL_SIZE = 4
local voxelPos = workspace.Terrain:WorldToCell(pos)

// my region will start at -100 under the desired position and end in +100 above desired position
local voxelRegion = Region3.new((voxelPos - Vector3.new(0,100,0)) * VOXEL_SIZE, (voxelPos + Vector3.new(1,100,1)) * VOXEL_SIZE)
local materialMap, occupancyMap = workspace.Terrain:ReadVoxels(voxelRegion, VOXEL_SIZE)

local steps = materialMap.Size.Y // this is actually 200 = height of the region

// now going from the very top of the region downwards and checking the terrain material
// (while it's AIR = no terrain found yet)
for i = steps, 1, -1 do

    if (materialMap[1][i][1] ~= Enum.Material.Air) then

        materialMap[1][i][1] ---> this is the material found on surface
        ((i-100) * VOXEL_SIZE) ---> this is the Y coordinate of the surface in world coordinates
    end
end

return false
end

编辑 2

原来@Kylaaa 的回答解决了所有问题。它还包括地形material!作为元组中的第 4 项。这意味着我的解决方案太复杂了,没有理由。使用他的解决方案。

尝试从起点向下投射光线,直到找到地形。 game.Workspace:FindPartOnRayWithWhitelist() 非常适合这个!

-- choose some starting point in world space
local xPos = 15
local yPos = 20
local zPos = 30

-- make a ray and point it downward.
-- NOTE - It's unusual, but you must specify a magnitude for the ray
local origin = Vector3.new(xPos, yPos, zPos)
local direction = Vector3.new(0, -100000, 0)
local ray = Ray.new(origin, direction)

-- search for the collision point with the terrain
local whitelist = { game.Workspace.Terrain }
local ignoreWater = true
local _, intersection, surfaceNormal, surfaceMaterial = game.Workspace:FindPartOnRayWithWhitelist(ray, whitelist, ignoreWater)

-- spawn a part at the intersection.
local p = Instance.new("Part")
p.Anchored = true
p.Size = Vector3.new(1, 1, 1)
p.Position = intersection -- <---- this Vector3 is the intersection point with the terrain
p.Parent = game.Workspace

如果您的模型在您调用 SetPrimaryPartCFrame() 时以不寻常的方式四处移动,请注意 Roblox 物理不喜欢相互穿透的对象。因此,模型通常会被向上推,直到它们不再相互渗透。 CanCollide = false 的对象不会有此问题,但如果它们不是 Anchored 或焊接到设置为 CanCollide = true 的部件,它们也会从世界中掉落。