Tengo un terreno generado en mi juego ROBLOX (colinas, llanos, ríos) y tengo un modelo de un árbol. El árbol es solo un grupo de "ladrillos", por lo que parece una especie de árbol de Minecraft.

Ahora quiero clonar ese árbol programáticamente en tiempo de ejecución y necesito colocar esa copia (clonar) en otro lugar del mapa.

Todo esto es facil. Pero después de darle a mi clon nuevas coordenadas (mantengo la coordenada del eje Y igual que mi árbol original), se coloca o en el aire, o bajo la superficie de mi terreno.

¿Cómo lo coloco directamente sobre el terreno? ¿O cómo obtengo la coordenada del eje Y de ese lugar en particular en el mapa?

¡Gracias!

EDITAR

Si bien la respuesta de @Kylaaa está perfectamente completa, aquí incluyo mi solución, mientras que también necesitaba información sobre el material del terreno en ese lugar (rocas / pasto / etc.)

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

EDITAR 2

Entonces resulta que la respuesta de @ Kylaaa lo resuelve todo. ¡Incluye también material de terreno! Como cuarto elemento de la tupla. Significa que mi solución es demasiado complicada sin ningún motivo. Usa su solución.

0
Enriqe 16 oct. 2019 a las 01:10

1 respuesta

La mejor respuesta

Trate de emitir rayos hacia abajo desde su punto de partida hasta que encuentre el terreno. game.Workspace:FindPartOnRayWithWhitelist() es genial para esto.

-- 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

Si tu modelo se mueve de manera inusual cuando llamas a SetPrimaryPartCFrame(), ten en cuenta que a la física de Roblox no le gustan los objetos que se compenetran. Por lo tanto, los modelos a menudo serán empujados hacia arriba hasta que ya no estén interpenetrados. Los objetos que son CanCollide = false no tendrán este problema, pero también desaparecerán del mundo si no están Anchored o si se sueldan a una pieza se establece en CanCollide = true.

2
Kylaaa 18 oct. 2019 a las 18:37