Terrain

显示已弃用

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

无法创建

地形允许您创建动态可变的环境,几乎没有任何延迟。它目前基于 4×4×4 网格的细胞,每个细胞都有一个数字在 0 和 1 之间代表几何图形的占位,并且材料的细胞。占位决定细胞的形状与周围细胞的形状的关系,并且结果是无格约束的假设。

了解更多信息,请参阅地形

概要

属性

继承自BasePart属性继承自PVInstance属性

方法

继承自BasePart方法继承自PVInstance方法

活动

继承自BasePart活动

属性

Decoration

不可写入脚本
读取并联

目前启用或禁用 地形材料上的动态草,尽管未来对该属性的修改可能会控制额外的装饰功能。

GrassLength

不可写入脚本
读取并联

指定草地的长度在 地形材料上,假设 Decoration 已启用。有效值在 0.1 和 1 之间。

MaterialColors

BinaryString
不可写入脚本
读取并联

MaterialColors 代表材料颜色精选能的编辑器,不能由脚本编辑 。

要获取材料的颜色,请使用: Terrain:GetMaterialColor()

要设置材料的颜色,请使用: Terrain:SetMaterialColor()

MaxExtents

只读
未复制
读取并联

显示最大可编辑区域的边界。

WaterColor

读取并联

地形水的色调。

WaterReflectance

读取并联

控制地形水域反射的不透明度。

WaterTransparency

读取并联

地形水的透明度。

WaterWaveSize

读取并联

设置地形水波的最大高度在格子中。 此前受到限制,最高高度必须在 0 和 1 之间。

WaterWaveSpeed

读取并联

设置地形水波每分钟上下移动的次数。目前,该参数受到 0 和 100 之间的限制。

方法

CellCenterToWorld

返回地形细胞中心的世界位置(x, y, z)。

参数


返回

CellCornerToWorld

返回网格元素的左下角位置(x,y,z)。

参数


返回

Clear

void

清除地形。


返回

void

CopyRegion

将一块地形存储在 TerrainRegion 对象中,以便它在后续可以重新加载。注意:TerrainRegion 数据在服务器和客户端之间不会重复。

参数

region: Region3int16

返回

代码示例

Terrain:CopyRegion

local terrainRegion = workspace.Terrain:CopyRegion(workspace.Terrain.MaxExtents)
workspace.Terrain:Clear()
task.wait(5)
workspace.Terrain:PasteRegion(terrainRegion, workspace.Terrain.MaxExtents.Min, true)

CountCells

返回地形中的非空填充区数。


返回

FillBall

void

在指定的空间中填充一个光滑的地形。

参数

center: Vector3

地形球的中心位置。

radius: number

地形球的半径。

material: Enum.Material

地形球的 Enum.Material


返回

void

代码示例

Filling a Ball of Terrain

local Workspace = game:GetService("Workspace")
-- Creates a ball of grass at (0,0,-10) with a radius of 10 studs
Workspace.Terrain:FillBall(Vector3.new(0, 0, -10), 10, Enum.Material.Grass)

FillBlock

void

填充平滑地形的方块,使用指定的位置、旋转角度、大小和材料。

参数

cframe: CFrame

地形砖块的 cframe (位置和方向)。

size: Vector3

方块的大小 - 高度和宽度。

material: Enum.Material

地形砖块的 Enum.Material


返回

void

FillCylinder

void

在指定的空间中填充一个圆柱。空间定义使用 CFrame、高度和半径。

使用


workspace.Terrain:FillCylinder(CFrame.new(0, 50, 0), 5, 30, Enum.Material.Asphalt)

参数

cframe: CFrame

地形圆柱的 CFrame (位置和方向)。

height: number

地形圆柱的高度。

radius: number

地形圆柱的半径。

material: Enum.Material

地形圆柱的 Enum.Material


返回

void

FillRegion

void

用光滑的地形填充一个 Region3 区域。

参数

region: Region3
resolution: number
material: Enum.Material

返回

void

FillWedge

void

FillWedge() 填充一个类似于楔形的体积TerrainEnum.Material 和区域的 0> Datatype.CFrame0> 和大小。 楔形的方向与相当的FillWedge()3> 相同。

参数

cframe: CFrame

填充楔子的位置和方向。

size: Vector3

填充楔子的大小。

material: Enum.Material

填充楔子的材料。


返回

void

GetMaterialColor

写入并联

为指定的地形材料返回当前的地形材料颜色。

参数

material: Enum.Material

返回

PasteRegion

void

在地形对象上应用一块地形。注意:TerrainRegion 数据不会在服务器和客户端之间重复。

参数

corner: Vector3int16
pasteEmptyCells: bool

返回

void

代码示例

Create, Copy and Paste Terrain

--[[
Note: The use of int16 variants for these API is the result of legacy code.
The underlying voxel grid system uses Vector3int32 (Vector3).
]]
local Workspace = game:GetService("Workspace")
local Terrain = Workspace.Terrain
-- Create a simple terrain region (a 10x10x10 block of grass)
local initialRegion = Region3.new(Vector3.zero, Vector3.one * 10)
Terrain:FillRegion(initialRegion, 4, Enum.Material.Grass)
-- Copy the region using Terrain:CopyRegion
local copyRegion = Region3int16.new(Vector3int16.new(0, 0, 0), Vector3int16.new(10, 10, 10))
local copiedRegion = Terrain:CopyRegion(copyRegion)
-- Define where to paste the region (in this example, offsetting by 5 studs on the X-axis)
local newRegionCorner = Vector3int16.new(5, 0, 0)
-- Paste the region using Terrain:PasteRegion
Terrain:PasteRegion(copiedRegion, newRegionCorner, true)

ReadVoxelChannels

写入并联

根据通道名称返回地形座标数据的区域。

参数

region: Region3

要读取的目标区域。必须对齐于 voxel 网格。如果区域太大,将抛出一个错误;目前区域的大小上限为 4194304 个 voxels³。

resolution: number

体素解析度。必须为 4。

channelIds: Array

需要从声量数据访问的通道ID阵列(string)。每个通道ID代表存储在声量体素中的数据类型。当前支持的ID为 {"SolidMaterial", "SolidOccupancy", "LiquidOccupancy"}


返回

根据 channelIds 输入返回 voxel 数据。键以各个通道 ID 的相应值为 3D 数据阵列代表。

  • SolidMaterial — 材料 Enum.Material 的 voxel。注意,Water 已不再支持,而是有一个含水的 voxel 的值为 0> LiquidOccupancy0> 。
  • SolidOccupancy — 占位体素材料的占位率,如在 SolidMaterial 频道中指定。这是一个值之间的 0 (空) 和 1 (满)。
  • LiquidOccupancy — 指定一个体素上的 Water 材料的占用值在 0 (无水) 和 1 (满水) 之间。如果 SolidOccupancy 是 1 和 0> SolidMaterial0> 不是 3> Ennum

字典还包含一个 Size 键,其值代表每个通道数据的 3D 阵列大小。

代码示例

Terrain:ReadVoxelChannels()

local REGION_START = Vector3.new(-20, -20, -20)
local REGION_END = Vector3.new(20, 20, 20)
local function printRegion(terrain, region)
local channelOutput = terrain:ReadVoxelChannels(region, 4, {"SolidOccupancy", "SolidMaterial", "LiquidOccupancy"})
local size = channelOutput.Size
for x = 1, size.X do
for y = 1, size.Y do
for z = 1, size.Z do
print(("(%2i, %2i, %2i): %.2f %s %.2f"):format(x, y, z, channelOutput.SolidOccupancy[x][y][z], channelOutput.SolidMaterial[x][y][z].Name, channelOutput.LiquidOccupancy[x][y][z]))
end
end
end
end
local region = Region3.new(REGION_START, REGION_END)
printRegion(workspace.Terrain, region)

ReadVoxels

写入并联

返回表格中的特定平滑地形区域。

参数

region: Region3

要读取的目标区域。必须对齐于 voxel 网格。如果区域太大,将抛出一个错误。目前限制为 4194304 个 voxels^3。

resolution: number

体素解析度。必须为 4。


返回

将原始声量数据返回为两个 3D 阵列。

  • materials - 3D 阵列的 Enum.Material 从目标区域。还包含一个大小为子列阵列的尺寸相等的字段。
  • occupancies - 3D 阵列的使用率值从目标区域。还包含一个大小为子阵列的大小值。

代码示例

Terrain:ReadVoxels() Code Example

local REGION_START = Vector3.new(-20, -20, -20)
local REGION_END = Vector3.new(20, 20, 20)
local function printRegion(terrain, region)
local materials, occupancies = terrain:ReadVoxels(region, 4)
local size = materials.Size -- Same as occupancies.Size
for x = 1, size.X, 1 do
for y = 1, size.Y, 1 do
for z = 1, size.Z, 1 do
print(("(%2i, %2i, %2i): %.2f %s"):format(x, y, z, occupancies[x][y][z], materials[x][y][z].Name))
end
end
end
end
local region = Region3.new(REGION_START, REGION_END)
printRegion(workspace.Terrain, region)

ReplaceMaterial

void

ReplaceMaterial 将特定 Enum.Material 替换为另一个材料。 它是一个在 Datatype.Region3 材料上的寻找和替换操作。 它的基本操作是在 Class.Terrain 材料上的查找和替换操作。

限制

调用此方法时,必须将 resolution 参数设置为 4 。此外,区域 3 必须对地形材料网格进行校准,即 Region3 的最小值和最大值的组成部分必须由 4 分割。使用 Region3:ExpandToGrid() 来使区域兼容此功能。

参数

region: Region3

发生替换操作的区域。

resolution: number

替换操作将在哪个解析度进场景;目前必须为 4。

sourceMaterial: Enum.Material

该替换的旧材料。

targetMaterial: Enum.Material

新的材料。


返回

void

代码示例

Terrain:ReplaceMaterial

local Workspace = game:GetService("Workspace")
local terrain = Workspace.Terrain
local region = Region3.new(Vector3.new(-20, -20, -20), Vector3.new(20, 20, 20))
local resolution = 4
local materialToReplace = Enum.Material.Grass
local replacementMaterial = Enum.Material.Asphalt
terrain:ReplaceMaterial(region, resolution, materialToReplace, replacementMaterial)

SetMaterialColor

void

为指定的地形材料设置当前的地形材料颜色。地形材料将向指定的颜色改变基本颜色。

参数

material: Enum.Material
value: Color3

返回

void

WorldToCell

返回网格元位,其中包含位置 位置

参数

position: Vector3

返回

WorldToCellPreferEmpty

返回网格元位,当位置在网格边时,空白网格元位。

参数

position: Vector3

返回

WorldToCellPreferSolid

返回网格元位,当位置在网格边上时,可优先使用不是空的网格元位。

参数

position: Vector3

返回

WriteVoxelChannels

void

使用数据库的 voxel 通道数据设置区域。

参数

region: Region3

写入的目标区域。必须与体素网格对齐。如果区域太大,将抛出错误;目前限制为 4194304 体素³。

resolution: number

体素解析度。必须为 4。

channels: Dictionary

ReadVoxelChannels() 返回值类似的 voxel 数据字典。 钥匙代表每个频道 ID 的相应值作为 3D 数据阵列。 字典可以支持单个或多个频道输入。

  • SolidMaterial — 材料 Enum.Material 的 体素oxel。注意,Water 已不再支持;相反,只有含水的 voxel 才应该输入为 0> SolidMaterial = Enum.Material.Air, LiquidOccupancy = x0>
  • SolidOccupancy — 占位体素材料的占位率,如在 SolidMaterial 频道中指定。这应该是一个值之间的 0 (空) 和 1 (满)。
  • LiquidOccupancy — 指定一个体素上的 Water 材料的占用值在 0 (无水) 和 1 (满水) 之间。如果 SolidOccupancy 是 1 和 0> SolidMaterial0> 不是 3> Ennum

返回

void

代码示例

Terrain:WriteVoxelChannels()

local region = Region3.new(Vector3.new(0, 0, 0), Vector3.new(64, 32, 64))
local RESOLUTION = 4
local OCC_EPSILON = 1/256
local function generateRandomTerrainInRegion(regionInput)
local region = regionInput:ExpandToGrid(4)
local size = region.Size / 4
local solidMaterials = {}
local solidOccupancies = {}
local waterOcc = {}
for x = 1, size.X do
table.insert(solidMaterials, {})
table.insert(solidOccupancies, {})
table.insert(waterOcc, {})
for y = 1, size.Y do
table.insert(solidMaterials[x], {})
table.insert(solidOccupancies[x], {})
table.insert(waterOcc[x], {})
for z = 1, size.Z do
local mat = if math.random() < 0.5 then Enum.Material.Air else Enum.Material.Sand
local occ = 0
local water = math.random()
if mat == Enum.Material.Sand then
occ = math.random() / 2 + 0.5
if occ > 1 - OCC_EPSILON then
water = 0 -- Solids cannot contain water
end
else
occ = 0
end
table.insert(solidMaterials[x][y], mat)
table.insert(solidOccupancies[x][y], occ)
table.insert(waterOcc[x][y], water)
end
end
end
return {SolidMaterial = solidMaterials, SolidOccupancy = solidOccupancies, LiquidOccupancy = waterOcc}
end
local regionContent = generateRandomTerrainInRegion(region)
workspace.Terrain:WriteVoxelChannels(region, 4, regionContent)

WriteVoxels

void

使用表格设置特定区域的平滑地形。

参数

region: Region3

目标区域。必须对齐于网格。如果区域太大,将会抛出错误。

resolution: number

体素解析度。必须为 4。

materials: Array

3D 阵列的枚数材料。 尺寸必须与目标区域的实体尺寸完全匹配。

occupancy: Array

3D 阵列(参考 0 和 1 之间的数字)。 尺寸必须与目标区域的实体大小完全匹配。


返回

void

代码示例

Example

local Workspace = game:GetService("Workspace")
local terrain = Workspace.Terrain
local resolution = 4
local region = Region3.new(Vector3.new(0, 0, 0), Vector3.new(16, 28, 20)):ExpandToGrid(resolution)
local materials = {
{
{
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air },
},
{
{
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Air },
},
{
{
Enum.Material.CrackedLava,
Enum.Material.Sand,
Enum.Material.Sand,
Enum.Material.Sand,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Air },
},
{
{
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air },
},
}
local occupancies = {
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 0.5, 0.5, 0.5, 0.5 },
{ 0, 0, 0, 0, 0 },
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 1, 1, 1, 0.5 },
{ 0, 1, 1, 1, 0 },
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 1, 1, 1, 0.5 },
{ 0, 1, 1, 1, 0 },
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 0.5, 0.5, 0.5, 0.5 },
{ 0, 0, 0, 0, 0 },
},
}
terrain:WriteVoxels(region, resolution, materials, occupancies)
Maximum Region Size

local REGION_START = Vector3.new(-20, -20, -20)
local REGION_END = Vector3.new(20, 20, 20)
local CFRAME = CFrame.new(0, 20, 0)
local SIZE = 50
local function getRegionVolumeVoxels(region)
local resolution = 4
local size = region.Size
return (size.x / resolution) * (size.y / resolution) * (size.z / resolution)
end
local function isRegionTooLargeForReadWriteVoxels(region)
return getRegionVolumeVoxels(region) > 4194304
end
local function isRegionTooLarge(region)
return getRegionVolumeVoxels(region) > 67108864
end
-- Helper function to get an axis-aligned Region3 from the given cframe and size
local function getAABBRegion(cframe, size)
local inv = cframe:Inverse()
local x = size * inv.RightVector
local y = size * inv.UpVector
local z = size * inv.LookVector
local w = math.abs(x.X) + math.abs(x.Y) + math.abs(x.Z)
local h = math.abs(y.X) + math.abs(y.Y) + math.abs(y.Z)
local d = math.abs(z.X) + math.abs(z.Y) + math.abs(z.Z)
local pos = cframe.Position
local halfSize = Vector3.new(w, h, d) / 2
return Region3.new(pos - halfSize, pos + halfSize):ExpandToGrid(4)
end
-- Specific functions for checking individual methods
local function isRegionTooLargeForFillBall(cframe, radius)
local diameter = radius * 2
return isRegionTooLarge(getAABBRegion(cframe, Vector3.new(diameter, diameter, diameter)))
end
local function isRegionTooLargeForFillBlock(cframe, size)
return isRegionTooLarge(getAABBRegion(cframe, size))
end
local function isRegionTooLargeForFillCylinder(cframe, height, radius)
local diameter = radius * 2
return isRegionTooLarge(getAABBRegion(cframe, Vector3.new(diameter, height, diameter)))
end
local function isRegionTooLargeForFillRegion(region)
return isRegionTooLarge(region)
end
local function isRegionTooLargeForFillWedge(cframe, size)
return isRegionTooLarge(getAABBRegion(cframe, size))
end
local function isRegionTooLargeForReplaceMaterial(region)
return isRegionTooLarge(region)
end
local region = Region3.new(REGION_START, REGION_END)
print(isRegionTooLargeForReadWriteVoxels(region))
print(isRegionTooLargeForFillBall(CFRAME, SIZE))
print(isRegionTooLargeForFillBlock(CFRAME, SIZE))
print(isRegionTooLargeForFillCylinder(CFRAME, SIZE, SIZE))
print(isRegionTooLargeForFillRegion(region))
print(isRegionTooLargeForFillWedge(CFRAME, SIZE))
print(isRegionTooLargeForReplaceMaterial(region))

活动