Skip to content

PhysicsUnit ​

概览 ​

字段值
KindUnit · 单位 Unit
Realmcommon

继承关系 ​

  • Unit(4 属性 / 25 函数 / 6 事件)
    • SpaceUnit(2 属性 / 9 函数)
      • BasePart(24 属性 / 9 函数)
        • [PhysicsUnit](21 属性 / 15 函数 / 4 事件)

继承成员 ​

3 个来源 / 19 属性 / 43 函数 / 6 事件

PhysicsUnit 是场景中的纯物理单位,用于承载由物理引擎驱动的刚体行为,可通过 BodyType、PhysicsActive、Mass、GravityEnabled、LinearVelocity、AngularVelocity 等属性刻画其运动状态与受力规则。它支持施加力、力矩与冲量,也支持按碰撞组和无碰撞对精细管理单位之间的碰撞关系,并通过碰撞进入与离开事件对外反馈接触结果。

适用场景 ​

常见于制作可被推动或击飞的物理道具、需要攀爬的机关,以及要求特定单位之间互不碰撞的场景,例如让角色穿过某些装饰体、却仍与地面发生碰撞。

使用要点 ​

通过 game:CreateUnit("PhysicsUnit", config) 或 World:CreateUnit("PhysicsUnit", config) 取得实例后,先设置 PhysicsMeshId、BodyType、PhysicsActive 等基础属性,再按需调整 Mass、GravityEnabled、LinearDamping 等物理参数。动态受力时可使用 ApplyForceToCenterOfMass、ApplyForceAtWorldPosition、ApplyTorque 施加持续作用,或用 ApplyImpulse 与 ApplyImpulseAtWorldPosition 施加瞬时冲量,并调用 GetVelocityAtPosition 查询指定位置的速度。碰撞关系可用 AddCollisionWithGroup 加入碰撞组、用 AddNoCollisionPairWithUnit 排除与目标单位的碰撞,同时监听 OnCollisionEnter 与 OnCollisionExit 处理接触的开始与结束。

注意事项 ​

引擎使用 Y 轴向上的坐标系(重力默认 [0, -9.8, 0])。施加力、冲量或力矩前,应确认单位使用 Enums.BodyType.Dynamic 且 PhysicsActive=true;施加向上的力应使用 Vector3.New(0,正值,0) 而非 Vector3.New(0,0,正值)。

代码示例 ​

创建动态物理单位并施加向上冲量 ​

lua
-- @runtime client
local world = game:GetService("World")
local physicsUnit = world:CreateUnit("PhysicsUnit", {
    Name = "JumpingBox",
    Position = Vector3.New(0, 3, 0),
    BodyType = Enums.BodyType.Dynamic,
    PhysicsActive = true,
})
physicsUnit:ApplyImpulse(Vector3.New(0, 120, 0))

属性 (21) ​

Name类型默认值说明
ModelBindParentBoolfalse是否让渲染模型跟随父节点的变换。
PhysicsMeshIdStringofficial://mesh/59268PhysicsMeshId 是 PhysicsUnit 的字符串属性,用于指定该物理单位所使用的物理资源 ID。
BodyTypeIntEnums.BodyType.Dynamic物理类型,决定该物理单元的模拟方式。
PhysicsActiveBooltrue是否启用物理模拟。
CollisionGroupString""该物理单元所属的碰撞组名称。
CanCollideBooltrue是否参与物理碰撞,关闭后物体将穿透其他物体
CanTouchBooltrueCanTouch 是 PhysicsUnit 的布尔属性,用于控制本物理单位的碰撞事件能否被其他单位触发。
CanTriggerBooltrueCanTrigger 是 PhysicsUnit 的布尔属性,用于控制本物理单位能否触发其他单位的碰撞事件。
MassFloat10物理单元的质量。
MasslessBoolfalse是否将物理单元视为无质量。
CustomPhysicalPropertiesPhysicalProperties-PhysicsUnit 的自定义物理材质属性,类型为 PhysicalProperties,可读写且可编辑。通过该属性可以读取或替换该物理单位当前使用的物理材质对象。
CenterOfMassVector3[0, 0, 0]PhysicsUnit 的质心属性,类型为 Vector3,表示该物理单元的质心位置。
GravityEnabledBooltrue是否对该物理单元应用重力。
UseIndividualGravityBoolfalse是否使用自定义重力,而非全局重力。
IndividualGravityValueVector3[0, -9.8, 0]PhysicsUnit 的自定义重力值属性,类型为 Vector3,可与 UseIndividualGravity 属性配合使用。
LinearDampingFloat0线速度阻尼系数,用于减缓物体的移动速度。
AngularDampingFloat0角速度阻尼系数,用于减缓物体的旋转速度。
AngularVelocityVector3[0, 0, 0]PhysicsUnit 的角速度属性,类型为 Vector3。
LinearVelocityVector3[0, 0, 0]PhysicsUnit 的线速度属性,类型为 Vector3。
ClimbableBoolfalse玩家角色是否可以攀爬此物体,仅对静态(Static)物体生效
CanQueryBooltrue是否参与空间射线检测(Raycast、Spherecast 等),关闭后射线将穿透此物体

关联类型 ​

事件 (4) ​

OnCollisionEnter ​

签名:OnCollisionEnter(otherUnit: Unit) 触发:local

PhysicsUnit 与其他单位发生碰撞时触发的本地事件,回调参数为碰撞对端的单位 otherUnit,类型为 Unit。

回调参数类型说明
otherUnitUnit与之发生碰撞的另一个物体

示例代码

监听编辑器动态物体开始碰撞

lua
-- @runtime client
local unit = game:GetService("World"):FindFirstChild("DynamicBody", true)
if unit == nil or not unit:IsA("PhysicsUnit") then return end
unit.OnCollisionEnter:Once(function(otherUnit)
    print("开始碰撞:", otherUnit.Name)
end)

OnCollisionExit ​

签名:OnCollisionExit(otherUnit: Unit) 触发:local

PhysicsUnit 与其他单位结束碰撞时触发的本地事件,回调参数为离开碰撞的对端单位 otherUnit,类型为 Unit。

回调参数类型说明
otherUnitUnit结束碰撞的另一个物体

示例代码

监听编辑器动态物体结束碰撞

lua
-- @runtime client
local unit = game:GetService("World"):FindFirstChild("DynamicBody", true)
if unit == nil or not unit:IsA("PhysicsUnit") then return end
unit.OnCollisionExit:Once(function(otherUnit)
    print("结束碰撞:", otherUnit.Name)
end)

OnLocalCollisionEnter ​

签名:OnLocalCollisionEnter(info: CollisionCallbackInfo) 触发:local

物理单元与其他对象发生碰撞并开始接触时,在本地端触发该事件。

回调参数类型说明
infoCollisionCallbackInfo碰撞回调信息

示例代码

监听 PhysicsUnit.OnLocalCollisionEnter 事件的示例。

lua
-- @runtime client
local physicsUnit = game:CreateUnit("PhysicsUnit", {})
physicsUnit.OnLocalCollisionEnter:Once(function(info)
    print("info: " .. tostring(info))
end)

OnLocalCollisionExit ​

签名:OnLocalCollisionExit(info: CollisionCallbackInfo) 触发:local

物理单元与其他对象结束碰撞接触时,在本地端触发该事件。

回调参数类型说明
infoCollisionCallbackInfo碰撞回调信息

示例代码

监听 PhysicsUnit.OnLocalCollisionExit 事件的示例。

lua
-- @runtime client
local physicsUnit = game:CreateUnit("PhysicsUnit", {})
physicsUnit.OnLocalCollisionExit:Once(function(info)
    print("info: " .. tostring(info))
end)

函数 (15) ​

AddCollisionWithGroup ​

签名:AddCollisionWithGroup(groupName: String) -> void

添加一个允许与当前物理单位发生碰撞的碰撞组。

参数类型说明
groupNameString要加入的碰撞组名称

返回值 void

示例代码

注册并添加允许碰撞的组

lua
-- @runtime server
local physicsService = game:GetService("PhysicsService")
local groupName = "MyGroup"
pcall(function() physicsService:RegisterCollisionGroup(groupName) end)
local unit = game:CreateUnit("PhysicsUnit", {})
unit:AddCollisionWithGroup(groupName)
print("当前碰撞组:", table.concat(unit:GetCollisionWithGroups(), ", "))

RemoveCollisionWithGroup ​

签名:RemoveCollisionWithGroup(groupName: String) -> void

从当前物理单位的允许碰撞列表中移除指定碰撞组。

参数类型说明
groupNameString要移除的碰撞组名称

返回值 void

示例代码

移除已添加的碰撞组

lua
-- @runtime server
local physicsService = game:GetService("PhysicsService")
local groupName = "TemporaryGroup"
pcall(function() physicsService:RegisterCollisionGroup(groupName) end)
local unit = game:CreateUnit("PhysicsUnit", {})
unit:AddCollisionWithGroup(groupName)
unit:RemoveCollisionWithGroup(groupName)

GetCollisionWithGroups ​

签名:GetCollisionWithGroups() -> Array<String>

获取当前物理单位允许发生碰撞的碰撞组名称列表。

返回值 Array<String>

示例代码

读取允许碰撞的组

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", {})
for _, groupName in ipairs(unit:GetCollisionWithGroups()) do
    print("允许碰撞组:", groupName)
end

ApplyForceToCenterOfMass ​

签名:ApplyForceToCenterOfMass(force: Vector3) -> void

在 PhysicsUnit 的质心处施加一个力,参数 force 为 Vector3 类型的力向量。

参数类型说明
forceVector3世界空间中的力向量

返回值 void

示例代码

给动态单位的质心施加向上的力

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyForceToCenterOfMass(Vector3.New(0, 200, 0))

ApplyForceAtLocalPosition ​

签名:ApplyForceAtLocalPosition(force: Vector3, localPosition: Vector3) -> void

在 PhysicsUnit 的局部坐标系指定的位置施加一个力,参数为力向量 force 与局部坐标位置 localPosition,二者均为 Vector3。

参数类型说明
forceVector3世界空间中的力向量
localPositionVector3物体局部空间中的施力点坐标

返回值 void

示例代码

在动态单位的局部位置施加力

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyForceAtLocalPosition(Vector3.New(0, 100, 0), Vector3.New(1, 0, 0))

ApplyForceAtWorldPosition ​

签名:ApplyForceAtWorldPosition(force: Vector3, worldPosition: Vector3) -> void

在 PhysicsUnit 的世界坐标指定位置施加一个力,参数为力向量 force 与世界坐标位置 worldPosition,二者均为 Vector3。

参数类型说明
forceVector3世界空间中的力向量
worldPositionVector3世界空间中的施力点坐标

返回值 void

示例代码

在动态单位的世界位置施加力

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { Position = Vector3.New(0, 5, 0), BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyForceAtWorldPosition(Vector3.New(0, 0, 100), unit.Position + Vector3.New(0, 0, 1))

ApplyTorque ​

签名:ApplyTorque(torque: Vector3) -> void

对 PhysicsUnit 施加力矩,参数 torque 为 Vector3 类型的力矩向量。

参数类型说明
torqueVector3各轴方向的力矩大小

返回值 void

示例代码

给动态单位施加绕 Y 轴的力矩

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyTorque(Vector3.New(0, 10, 0))

ApplyImpulse ​

签名:ApplyImpulse(impulse: Vector3) -> void

在 PhysicsUnit 的质心处施加一个冲量,参数 impulse 为 Vector3 类型的冲量向量。

参数类型说明
impulseVector3冲量向量,方向和大小决定瞬时速度变化

返回值 void

示例代码

给动态单位的质心施加向上冲量

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyImpulse(Vector3.New(0, 50, 0))

ApplyImpulseAtLocalPosition ​

签名:ApplyImpulseAtLocalPosition(impulse: Vector3, localPosition: Vector3) -> void

在 PhysicsUnit 的局部坐标系指定位置施加一个冲量,参数为冲量向量 impulse 与局部坐标位置 localPosition,二者均为 Vector3。

参数类型说明
impulseVector3冲量向量
localPositionVector3物体局部空间中的冲量施加点坐标

返回值 void

示例代码

在动态单位的局部位置施加冲量

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyImpulseAtLocalPosition(Vector3.New(0, 0, 50), Vector3.New(0, 0, 1))

ApplyImpulseAtWorldPosition ​

签名:ApplyImpulseAtWorldPosition(impulse: Vector3, worldPosition: Vector3) -> void

在 PhysicsUnit 的世界坐标指定位置施加一个冲量,参数为冲量向量 impulse 与世界坐标位置 worldPosition,二者均为 Vector3。

参数类型说明
impulseVector3冲量向量
worldPositionVector3世界空间中的冲量施加点坐标

返回值 void

示例代码

在动态单位的世界位置施加冲量

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { Position = Vector3.New(0, 5, 0), BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyImpulseAtWorldPosition(Vector3.New(50, 0, 0), unit.Position + Vector3.New(1, 0, 0))

GetVelocityAtPosition ​

签名:GetVelocityAtPosition(position: Vector3) -> Vector3

获取 PhysicsUnit 在指定世界坐标位置处的速度,参数 position 为世界坐标 Vector3,返回 Vector3 类型的速度值。

参数类型说明
positionVector3要查询速度的世界空间坐标点

返回值 Vector3

示例代码

读取动态单位指定世界位置的速度

lua
-- @runtime client
local unit = game:CreateUnit("PhysicsUnit", { Position = Vector3.New(0, 5, 0), BodyType = Enums.BodyType.Dynamic, PhysicsActive = true })
unit:ApplyImpulse(Vector3.New(50, 0, 0))
local velocity = unit:GetVelocityAtPosition(unit.Position + Vector3.New(1, 0, 0))
print("指定位置速度:", velocity)

AddNoCollisionPairWithUnit ​

签名:AddNoCollisionPairWithUnit(targetUnit: SpaceUnit) -> void

为当前 PhysicsUnit 与参数 targetUnit 添加不碰撞配对,使这两个单位之间不再发生碰撞。targetUnit 的类型为 SpaceUnit,该函数没有返回值。

参数类型说明
targetUnitSpaceUnit要互不碰撞的目标单位

返回值 void

示例代码

与目标空间单位禁用碰撞

lua
-- @runtime client
local world = game:GetService("World")
local physicsUnit = world:CreateUnit("PhysicsUnit", { Position = Vector3.New(0, 2, 0) })
local targetUnit = world:CreateUnit("WorldUnit", { Position = Vector3.New(2, 2, 0) })

physicsUnit:AddNoCollisionPairWithUnit(targetUnit)
print("已添加互不碰撞目标:", targetUnit.Name)

RemoveNoCollisionPairWithUnit ​

签名:RemoveNoCollisionPairWithUnit(targetUnit: SpaceUnit) -> void

移除当前 PhysicsUnit 与参数 targetUnit 之间此前建立的不碰撞配对,使两者恢复正常的碰撞关系。targetUnit 的类型为 SpaceUnit,该函数没有返回值。

参数类型说明
targetUnitSpaceUnit要恢复碰撞的目标单位

返回值 void

示例代码

恢复与目标空间单位碰撞

lua
-- @runtime client
local world = game:GetService("World")
local physicsUnit = world:CreateUnit("PhysicsUnit", { Position = Vector3.New(0, 2, 0) })
local targetUnit = world:CreateUnit("WorldUnit", { Position = Vector3.New(2, 2, 0) })

physicsUnit:AddNoCollisionPairWithUnit(targetUnit)
physicsUnit:RemoveNoCollisionPairWithUnit(targetUnit)
print("已恢复与目标单位的碰撞:", targetUnit.Name)

RemoveAllNoCollisionPairWithUnit ​

签名:RemoveAllNoCollisionPairWithUnit() -> void

移除所有已添加的不碰撞单位对。

返回值 void

示例代码

调用 PhysicsUnit:RemoveAllNoCollisionPairWithUnit 的示例。

lua
-- @runtime client
local physicsUnit = game:CreateUnit("PhysicsUnit", {})
physicsUnit:RemoveAllNoCollisionPairWithUnit()
print("调用完成", physicsUnit)

GetNoCollisionPairUnitList ​

签名:GetNoCollisionPairUnitList() -> Array&lt;SpaceUnit&gt;

获取当前 PhysicsUnit 上已记录的全部不碰撞配对单位,返回值为数组,数组元素类型为 SpaceUnit。

返回值 Array<SpaceUnit>

示例代码

查询不碰撞单位列表

lua
-- @runtime client
local world = game:GetService('World')
local unitA = world:CreateUnit('PhysicsUnit', {})
local unitB = world:CreateUnit('PhysicsUnit', {})
if unitA == nil or unitB == nil then return end
unitA:AddNoCollisionPairWithUnit(unitB)
local units = unitA:GetNoCollisionPairUnitList()
for _, other in ipairs(units) do
    print('不碰撞单位:', other.Name)
end