BasePart 是一个在 Workspace 内渲染并被物理模拟的世界对象的抽象基类。BasePart 有多个实现,最常见的是 Part 和 MeshPart。其他的包括 WedgePart、SpawnLocation 和单例的 Terrain 对象。通常,当文档提到“部件”时,大多数 BasePart 实现都会起作用,而不仅仅是 Part。
有关如何将 BaseParts 分组到模拟刚体的信息,请参见 Assemblies。
许多不同的对象与 BasePart 交互(除了 Terrain),包括:
- Attachments 可以添加到 BasePart,以指定与该部件相关的 CFrames。这些通常由物理 Constraint 对象使用,如在 Mechanical Constraints 和 Mover Constraints 中所述。
概要
属性
决定一个部件是否被物理影响而无法移动。
部件组件的角速度。
部件组件的质心在世界空间中的位置。
部件组件的线速度。
部件组件的总质量。
对组件根部件的引用。
决定部件是否与音频模拟物理交互,类似于 CastShadow 对于光照。
确定部件背面表面的类型。
确定部件底面的类型。
确定部件的颜色。
决定 BasePart 在世界中的位置和方向。
决定部件是否可以与其他部件碰撞。
决定部件在空间查询操作中是否被考虑。
决定 Touched 和 TouchEnded 事件是否在该部件上触发。
决定部件是否投射阴影。
描述部件质心所在的世界位置。
描述部件的碰撞组名称。
决定部件的颜色。
指示部件的当前物理属性。
决定部件的多个物理属性。
用于启用或禁用部件和组件上的空气动力学力。
物理引擎认为的 BasePart 的实际物理大小。
决定部件前面表面的类型。
决定部件左面表面的类型。
决定 BasePart.Transparency 的只对本地客户端可见的乘数。
决定部件是否可以在 Studio 中被选择。
描述部件的质量,即其密度和体积的乘积。
决定部件对刚体的总质量或惯性的贡献。
决定部件的纹理和默认物理属性。
MaterialVariant 的名称。
描述部件在世界中的旋转。
指定部件的枢轴偏移量。
描述部件在世界中的位置。
最后一次记录的物理更新以来已经过去的时间。
决定一个部件反射天空盒的程度。
描述通过 Resize() 方法允许的最小大小变化。
描述一个部件可以被调整大小的面。
确定部件右面的表面类型。
确定一个组件的根部件的主要规则。
部件在三个轴上的旋转角度(以度为单位)。
确定一个部件的尺寸(长度、宽度、高度)。
确定部件上面的表面类型。
确定一个部件的透视度(透明度的反向)。
方法
对组件施加角动量脉冲。
在组件的 质量中心 应用一个脉冲。
在指定位置对组件施加脉冲。
返回部件是否可以相互碰撞。
检查是否可以设置部件的网络所有权。
返回通过任何刚性连接连接到该对象的部件表。
返回连接到该部件的所有连接或约束。
返回 Mass 属性的值。
返回此部件的网络所有者玩家,如果是服务器则返回 nil。
如果游戏引擎自动决定此部件的网络所有者,则返回 true。
返回所有与该部件相交且 BasePart.CanCollide 为 true 的部件的表。
返回相对于此部件在给定位置的部件组件的线性速度。
- IntersectAsync(parts : Instances,collisionfidelity : Enum.CollisionFidelity,renderFidelity : Enum.RenderFidelity):Instance
从相交的几何形状创建新的 IntersectOperation。
如果对象连接到一个可以将其固定在原地的部件(例如 Anchored 部件),则返回 true,否则返回 false。
像使用 Studio 调整工具一样更改对象的大小。
将给定的玩家设置为此及所有连接部件的网络所有者。
允许游戏引擎动态决定谁将处理部件的物理(客户端之一或服务器)。
- SubtractAsync(parts : Instances,collisionfidelity : Enum.CollisionFidelity,renderFidelity : Enum.RenderFidelity):Instance
从部件创建新的 UnionOperation,减去给定数组中所占的几何形状。
- UnionAsync(parts : Instances,collisionfidelity : Enum.CollisionFidelity,renderFidelity : Enum.RenderFidelity):Instance
从部件创建新的 UnionOperation,加上给定数组中所占的几何形状。
方法
获取 PVInstance 的支点。
转换 PVInstance 及其所有子代 PVInstances,使得支点现在位于指定的 CFrame。
活动
当一个部件由于物理运动停止接触另一个部件时触发。
当一个部件由于物理运动接触另一个部件时触发。
属性
Anchored
代码示例
local part = script.Parent
-- 创建一个 ClickDetector,以便我们可以知道部件何时被点击
local cd = Instance.new("ClickDetector", part)
-- 此函数根据部件的 Anchored 状态更新部件的外观
local function updateVisuals()
if part.Anchored then
-- 当部件已固定时...
part.BrickColor = BrickColor.new("鲜红")
part.Material = Enum.Material.DiamondPlate
else
-- 当部件未固定时...
part.BrickColor = BrickColor.new("鲜黄色")
part.Material = Enum.Material.Wood
end
end
local function onToggle()
-- 切换固定属性
part.Anchored = not part.Anchored
-- 更新砖块的视觉状态
updateVisuals()
end
-- 更新后,开始监听点击
updateVisuals()
cd.MouseClick:Connect(onToggle)
AssemblyAngularVelocity
AssemblyCenterOfMass
AssemblyLinearVelocity
AssemblyMass
AssemblyRootPart
AudioCanCollide
BackSurface
BottomSurface
BrickColor
CFrame
代码示例
local part = script.Parent:WaitForChild("Part")
local otherPart = script.Parent:WaitForChild("OtherPart")
-- 将零件的 CFrame 重置为 (0, 0, 0),没有旋转。
-- 这有时被称为“单位”CFrame
part.CFrame = CFrame.new()
-- 设置为特定位置 (X, Y, Z)
part.CFrame = CFrame.new(0, 25, 10)
-- 与上面相同,但使用 Vector3
local point = Vector3.new(0, 25, 10)
part.CFrame = CFrame.new(point)
-- 将零件的 CFrame 设置为位于一个点,面向另一个点
local lookAtPoint = Vector3.new(0, 20, 15)
part.CFrame = CFrame.lookAt(point, lookAtPoint)
-- 在本地 X 轴上将零件的 CFrame 旋转 pi/2 弧度
part.CFrame = part.CFrame * CFrame.Angles(math.pi / 2, 0, 0)
-- 在本地 Y 轴上将零件的 CFrame 旋转 45 度
part.CFrame = part.CFrame * CFrame.Angles(0, math.rad(45), 0)
-- 在全局 Z 轴上将零件的 CFrame 旋转 180 度(注意顺序!)
part.CFrame = CFrame.Angles(0, 0, math.pi) * part.CFrame -- Pi 弧度等于 180 度
-- 组合两个 CFrame 使用 *(乘法运算符)
part.CFrame = CFrame.new(2, 3, 4) * CFrame.new(4, 5, 6) --> 等于 CFrame.new(6, 8, 10)
-- 与代数乘法不同,CFrame 组合不是交换的:a * b 不一定等于 b * a!
-- 想象 * 为一系列有序的动作。例如,以下行产生不同的 CFrame:
-- 1) 将零件在 X 轴上滑动 5 个单位。
-- 2) 绕 Y 轴将零件旋转 45 度。
part.CFrame = CFrame.new(5, 0, 0) * CFrame.Angles(0, math.rad(45), 0)
-- 1) 绕 Y 轴将零件旋转 45 度。
-- 2) 将零件在 X 轴上滑动 5 个单位。
part.CFrame = CFrame.Angles(0, math.rad(45), 0) * CFrame.new(5, 0, 0)
-- 没有“CFrame 除法”,而是简单地“执行逆操作”。
part.CFrame = CFrame.new(4, 5, 6) * CFrame.new(4, 5, 6):Inverse() --> 等于 CFrame.new(0, 0, 0)
part.CFrame = CFrame.Angles(0, 0, math.pi) * CFrame.Angles(0, 0, math.pi):Inverse() --> 等于 CFrame.Angles(0, 0, 0)
-- 将一个零件相对于另一个零件放置(在这种情况下,将我们的零件放在 otherPart 上面)
part.CFrame = otherPart.CFrame * CFrame.new(0, part.Size.Y / 2 + otherPart.Size.Y / 2, 0)
CanCollide
代码示例
-- 粘贴到一个高部件的脚本中
local part = script.Parent
local OPEN_TIME = 1
-- 这个门现在可以打开吗?
local debounce = false
local function open()
part.CanCollide = false
part.Transparency = 0.7
part.BrickColor = BrickColor.new("黑色")
end
local function close()
part.CanCollide = true
part.Transparency = 0
part.BrickColor = BrickColor.new("亮蓝色")
end
local function onTouch(otherPart)
-- 如果门已经打开,则不执行任何操作
if debounce then
print("D")
return
end
-- 检查是否被类人角色触碰
local human = otherPart.Parent:FindFirstChildOfClass("Humanoid")
if not human then
print("不是类人角色")
return
end
-- 执行门打开序列
debounce = true
open()
task.wait(OPEN_TIME)
close()
debounce = false
end
part.Touched:Connect(onTouch)
close()
CanQuery
CanTouch
CastShadow
CenterOfMass
CollisionGroup
代码示例
local PhysicsService = game:GetService("PhysicsService")
local collisionGroupBall = "CollisionGroupBall"
local collisionGroupDoor = "CollisionGroupDoor"
-- 注册碰撞组
PhysicsService:RegisterCollisionGroup(collisionGroupBall)
PhysicsService:RegisterCollisionGroup(collisionGroupDoor)
-- 将部分分配给碰撞组
script.Parent.BallPart.CollisionGroup = collisionGroupBall
script.Parent.DoorPart.CollisionGroup = collisionGroupDoor
-- 设置组之间为不可相撞并检查结果
PhysicsService:CollisionGroupSetCollidable(collisionGroupBall, collisionGroupDoor, false)
print(PhysicsService:CollisionGroupsAreCollidable(collisionGroupBall, collisionGroupDoor)) --> false
Color
代码示例
-- 粘贴到 StarterCharacterScripts 中的一个脚本内
-- 然后播放游戏,并调整你角色的健康值
local char = script.Parent
local human = char.Humanoid
local colorHealthy = Color3.new(0.4, 1, 0.2)
local colorUnhealthy = Color3.new(1, 0.4, 0.2)
local function setColor(color)
for _, child in pairs(char:GetChildren()) do
if child:IsA("BasePart") then
child.Color = color
while child:FindFirstChildOfClass("Decal") do
child:FindFirstChildOfClass("Decal"):Destroy()
end
elseif child:IsA("Accessory") then
child.Handle.Color = color
local mesh = child.Handle:FindFirstChildOfClass("SpecialMesh")
if mesh then
mesh.TextureId = ""
end
elseif child:IsA("Shirt") or child:IsA("Pants") then
child:Destroy()
end
end
end
local function update()
local percentage = human.Health / human.MaxHealth
-- 根据你的健康百分比插值生成颜色
-- 颜色从 colorHealthy (100%) ----- > colorUnhealthy (0%)
local color = Color3.new(
colorHealthy.R * percentage + colorUnhealthy.r * (1 - percentage),
colorHealthy.G * percentage + colorUnhealthy.g * (1 - percentage),
colorHealthy.B * percentage + colorUnhealthy.b * (1 - percentage)
)
setColor(color)
end
update()
human.HealthChanged:Connect(update)
CurrentPhysicalProperties
CustomPhysicalProperties
代码示例
local part = script.Parent
-- 这将使部件变得轻且有弹性!
local DENSITY = 0.3
local FRICTION = 0.1
local ELASTICITY = 1
local FRICTION_WEIGHT = 1
local ELASTICITY_WEIGHT = 1
local physProperties = PhysicalProperties.new(DENSITY, FRICTION, ELASTICITY, FRICTION_WEIGHT, ELASTICITY_WEIGHT)
part.CustomPhysicalProperties = physProperties
EnableFluidForces
ExtentsCFrame
ExtentsSize
FrontSurface
LeftSurface
LocalTransparencyModifier
Locked
代码示例
-- 粘贴到您想要解锁的模型中的脚本内
local model = script.Parent
-- 此函数通过模型的层级结构递归并解锁
-- 它遇到的每个部分。
local function recursiveUnlock(object)
if object:IsA("BasePart") then
object.Locked = false
end
-- 在对象的子级上调用相同的函数
-- 如果对象没有子级,递归过程将停止
for _, child in pairs(object:GetChildren()) do
recursiveUnlock(child)
end
end
recursiveUnlock(model)
Mass
Massless
Material
MaterialVariant
Orientation
代码示例
local part = script.Parent
local INCREMENT = 360 / 20
-- 不断旋转部件
while true do
for degrees = 0, 360, INCREMENT do
-- 仅设置Y轴旋转
part.Rotation = Vector3.new(0, degrees, 0)
-- 更好的方法是设置CFrame
--part.CFrame = CFrame.new(part.Position) * CFrame.Angles(0, math.rad(degrees), 0)
task.wait()
end
end
PivotOffset
代码示例
local function resetPivot(model)
local boundsCFrame = model:GetBoundingBox()
if model.PrimaryPart then
model.PrimaryPart.PivotOffset = model.PrimaryPart.CFrame:ToObjectSpace(boundsCFrame)
else
model.WorldPivot = boundsCFrame
end
end
resetPivot(script.Parent)
local function createHand(length, width, yOffset)
local part = Instance.new("Part")
part.Size = Vector3.new(width, 0.1, length)
part.Material = Enum.Material.Neon
part.PivotOffset = CFrame.new(0, -(yOffset + 0.1), length / 2)
part.Anchored = true
part.Parent = workspace
return part
end
local function positionHand(hand, fraction)
hand:PivotTo(CFrame.fromEulerAnglesXYZ(0, -fraction * 2 * math.pi, 0))
end
-- 创建表盘
for i = 0, 11 do
local dialPart = Instance.new("Part")
dialPart.Size = Vector3.new(0.2, 0.2, 1)
dialPart.TopSurface = Enum.SurfaceType.Smooth
if i == 0 then
dialPart.Size = Vector3.new(0.2, 0.2, 2)
dialPart.Color = Color3.new(1, 0, 0)
end
dialPart.PivotOffset = CFrame.new(0, -0.1, 10.5)
dialPart.Anchored = true
dialPart:PivotTo(CFrame.fromEulerAnglesXYZ(0, (i / 12) * 2 * math.pi, 0))
dialPart.Parent = workspace
end
-- 创建指针
local hourHand = createHand(7, 1, 0)
local minuteHand = createHand(10, 0.6, 0.1)
local secondHand = createHand(11, 0.2, 0.2)
-- 运行时钟
while true do
local components = os.date("*t")
positionHand(hourHand, (components.hour + components.min / 60) / 12)
positionHand(minuteHand, (components.min + components.sec / 60) / 60)
positionHand(secondHand, components.sec / 60)
task.wait()
end
Position
ReceiveAge
Reflectance
ResizeIncrement
ResizeableFaces
代码示例
-- 将此脚本放置在几种类型的 BasePart 中,例如
-- Part、TrussPart、WedgePart、CornerWedgePart 等。
local part = script.Parent
-- 为这个部件创建一个控制点对象
local handles = Instance.new("Handles")
handles.Adornee = part
handles.Parent = part
-- 手动指定适用此控制点的面
handles.Faces = Faces.new(Enum.NormalId.Top, Enum.NormalId.Front, Enum.NormalId.Left)
-- 或者,使用该部件可以调整大小的面。
-- 如果该部件是只有两个大小维度的 TrussPart
-- 且长度为 2,则可调整面将只有两个
-- 启用的面。对于其他部件,将启用所有面。
handles.Faces = part.ResizeableFaces
RightSurface
RootPriority
Rotation
Size
代码示例
local TOWER_BASE_SIZE = 30
local position = Vector3.new(50, 50, 50)
local hue = math.random()
local color0 = Color3.fromHSV(hue, 1, 1)
local color1 = Color3.fromHSV((hue + 0.35) % 1, 1, 1)
local model = Instance.new("Model")
model.Name = "Tower"
for i = TOWER_BASE_SIZE, 1, -2 do
local part = Instance.new("Part")
part.Size = Vector3.new(i, 2, i)
part.Position = position
part.Anchored = true
part.Parent = model
-- 从 color0 到 color1 的渐变
local perc = i / TOWER_BASE_SIZE
part.Color = Color3.new(
color0.R * perc + color1.R * (1 - perc),
color0.G * perc + color1.G * (1 - perc),
color0.B * perc + color1.B * (1 - perc)
)
position = position + Vector3.new(0, part.Size.Y, 0)
end
model.Parent = workspace
TopSurface
Transparency
代码示例
-- 粘贴到一个高部件的脚本中
local part = script.Parent
local OPEN_TIME = 1
-- 这个门现在可以打开吗?
local debounce = false
local function open()
part.CanCollide = false
part.Transparency = 0.7
part.BrickColor = BrickColor.new("黑色")
end
local function close()
part.CanCollide = true
part.Transparency = 0
part.BrickColor = BrickColor.new("亮蓝色")
end
local function onTouch(otherPart)
-- 如果门已经打开,则不执行任何操作
if debounce then
print("D")
return
end
-- 检查是否被类人角色触碰
local human = otherPart.Parent:FindFirstChildOfClass("Humanoid")
if not human then
print("不是类人角色")
return
end
-- 执行门打开序列
debounce = true
open()
task.wait(OPEN_TIME)
close()
debounce = false
end
part.Touched:Connect(onTouch)
close()
方法
AngularAccelerationToTorque
参数
返回
CanSetNetworkOwnership
返回
代码示例
local part = workspace:FindFirstChild("Part")
if part and part:IsA("BasePart") then
local canSet, errorReason = part:CanSetNetworkOwnership()
if canSet then
print(part:GetFullName() .. "的网络所有权可以被更改!")
else
warn("无法更改" .. part:GetFullName() .. "的网络所有权,因为:" .. errorReason)
end
end
GetJoints
返回
GetMass
返回
代码示例
local myPart = Instance.new("Part")
myPart.Size = Vector3.new(4, 6, 4)
myPart.Anchored = true
myPart.Parent = workspace
local myMass = myPart:GetMass()
print("我零件的质量是 " .. myMass)
GetNoCollisionConstraints
返回
GetTouchingParts
返回
IntersectAsync
参数
返回
SetNetworkOwnershipAuto
返回
SubtractAsync
参数
返回
代码示例
local Workspace = game:GetService("Workspace")
local mainPart = script.Parent.PartA
local otherParts = { script.Parent.PartB, script.Parent.PartC }
-- 执行减法操作
local success, newSubtract = pcall(function()
return mainPart:SubtractAsync(otherParts)
end)
-- 如果操作成功,将其放置在相同的位置并将其父级设为工作区
if success and newSubtract then
newSubtract.Position = mainPart.Position
newSubtract.Parent = Workspace
end
-- 销毁操作后保持完整的原始部分
mainPart:Destroy()
for _, part in otherParts do
part:Destroy()
end
UnionAsync
参数
返回
代码示例
local Workspace = game:GetService("Workspace")
local mainPart = script.Parent.PartA
local otherParts = { script.Parent.PartB, script.Parent.PartC }
-- 执行联合操作
local success, newUnion = pcall(function()
return mainPart:UnionAsync(otherParts)
end)
-- 如果操作成功,将其放置在相同位置并将其父对象设置为工作区
if success and newUnion then
newUnion.Position = mainPart.Position
newUnion.Parent = Workspace
end
-- 销毁在操作后保持完好的原始部分
mainPart:Destroy()
for _, part in otherParts do
part:Destroy()
end
活动
TouchEnded
参数
代码示例
local part = script.Parent
local billboardGui = Instance.new("BillboardGui")
billboardGui.Size = UDim2.new(0, 200, 0, 50)
billboardGui.Adornee = part
billboardGui.AlwaysOnTop = true
billboardGui.Parent = part
local tl = Instance.new("TextLabel")
tl.Size = UDim2.new(1, 0, 1, 0)
tl.BackgroundTransparency = 1
tl.Parent = billboardGui
local numTouchingParts = 0
local function onTouch(otherPart)
print("开始接触: " .. otherPart.Name)
numTouchingParts = numTouchingParts + 1
tl.Text = numTouchingParts
end
local function onTouchEnded(otherPart)
print("接触结束: " .. otherPart.Name)
numTouchingParts = numTouchingParts - 1
tl.Text = numTouchingParts
end
part.Touched:Connect(onTouch)
part.TouchEnded:Connect(onTouchEnded)
Touched
参数
代码示例
local part = script.Parent
local billboardGui = Instance.new("BillboardGui")
billboardGui.Size = UDim2.new(0, 200, 0, 50)
billboardGui.Adornee = part
billboardGui.AlwaysOnTop = true
billboardGui.Parent = part
local tl = Instance.new("TextLabel")
tl.Size = UDim2.new(1, 0, 1, 0)
tl.BackgroundTransparency = 1
tl.Parent = billboardGui
local numTouchingParts = 0
local function onTouch(otherPart)
print("开始接触: " .. otherPart.Name)
numTouchingParts = numTouchingParts + 1
tl.Text = numTouchingParts
end
local function onTouchEnded(otherPart)
print("接触结束: " .. otherPart.Name)
numTouchingParts = numTouchingParts - 1
tl.Text = numTouchingParts
end
part.Touched:Connect(onTouch)
part.TouchEnded:Connect(onTouchEnded)
local model = script.Parent
local function onTouched(otherPart)
-- 忽略与模型本身接触的实例
if otherPart:IsDescendantOf(model) then
return
end
print(model.Name .. " 与 " .. otherPart.Name .. " 碰撞")
end
for _, child in pairs(model:GetChildren()) do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
end
end