Skip to content

PhysicsUnit

概览

字段
KindUnit · 单位 Unit
Realmcommon

继承关系

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

继承成员

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

PhysicsUnit 是场景中承担真实物理模拟的单位,具备质量、质心、重力、阻尼等刚体属性,可配置碰撞与射线检测。它提供完整的力与冲量施加接口,能够驱动对象移动、旋转或被击飞,同时通过碰撞组和碰撞对管理单位间的交互,碰撞事件可用于实现打击、触发等玩法逻辑。

适用场景

在需要物理反馈的玩法中,例如制作可推动的箱子、受击飞出的道具、触发碰撞的机关或物理弹射装置时,通常会创建 PhysicsUnit 并开启物理,再施加力或冲量使其运动,并监听碰撞事件驱动后续逻辑。

使用要点

通过 game:CreateUnit("PhysicsUnit", 配置表) 或 World:CreateUnit 创建实例,并设置 BodyType、PhysicsActive、CollisionGroup 等属性以启用物理。需要驱动运动时,可调用 ApplyForceToCenterOfMass、ApplyImpulse 或 ApplyTorque 施加力、冲量与力矩。碰撞检测方面,监听 OnCollisionEnter 与 OnCollisionExit 事件,并可用 AddCollisionWithGroup、AddNoCollisionPairWithUnit 管理碰撞关系。

注意事项

引擎使用 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/59268用于物理碰撞检测的网格资源 ID。
BodyTypeIntEnums.BodyType.Dynamic物理类型,决定该物理单元的模拟方式。
PhysicsActiveBooltrue是否启用物理模拟。
CollisionGroupString""该物理单元所属的碰撞组名称。
CanCollideBooltrue是否参与物理碰撞,关闭后物体将穿透其他物体
CanTouchBooltrue控制该物理单元是否能够被其他单元触发碰撞事件。
CanTriggerBooltrue控制该物理单元是否能够触发其他单元的碰撞事件。
MassFloat10物理单元的质量。
MasslessBoolfalse是否将物理单元视为无质量。
CustomPhysicalPropertiesPhysicalProperties-自定义物理材质属性,可覆盖默认的物理参数。
CenterOfMassVector3[0, 0, 0]物理单位的质心位置,相对于物体自身的局部坐标系。
GravityEnabledBooltrue是否对该物理单元应用重力。
UseIndividualGravityBoolfalse是否使用自定义重力,而非全局重力。
IndividualGravityValueVector3[0, -9.8, 0]当 UseIndividualGravity 为 true 时,物理单位使用的自定义重力加速度。
LinearDampingFloat0线速度阻尼系数,用于减缓物体的移动速度。
AngularDampingFloat0角速度阻尼系数,用于减缓物体的旋转速度。
AngularVelocityVector3[0, 0, 0]物理单位的角速度,表示物体绕各轴的旋转速率。
LinearVelocityVector3[0, 0, 0]物理单位的线速度,表示物体在三维空间中的移动速度。
ClimbableBoolfalse玩家角色是否可以攀爬此物体,仅对静态(Static)物体生效
CanQueryBooltrue是否参与空间射线检测(Raycast、Spherecast 等),关闭后射线将穿透此物体

关联类型

事件 (4)

OnCollisionEnter

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

PhysicsUnit 与其他单位发生碰撞接触时触发的事件。事件触发时,参数 otherUnit 为与该 PhysicsUnit 发生碰撞的另一个单位实例。

回调参数类型说明
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 为与该 PhysicsUnit 解除碰撞的另一个单位实例。

回调参数类型说明
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

在物理单位的质心处施加一个力。

参数类型说明
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

在物理单位的局部坐标位置施加一个力。

参数类型说明
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

在物理单位的世界坐标位置施加一个力。

参数类型说明
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

在物理单位上施加一个力矩,使其绕质心旋转。

参数类型说明
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

在物理单位的质心处施加一个冲量,瞬间改变物体的速度。

参数类型说明
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

在物理单位的局部坐标位置施加一个冲量。

参数类型说明
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

在物理单位的世界坐标位置施加一个冲量。

参数类型说明
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

获取物理单位上指定世界坐标位置的速度。

参数类型说明
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

添加一个不碰撞的单位对,使当前物理单位与目标单位之间不发生碰撞。

参数类型说明
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

移除一个不碰撞的单位对,恢复当前物理单位与目标单位之间的碰撞。

参数类型说明
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;

获取与当前物理单位不碰撞的所有单位列表。

返回值 Array<SpaceUnit>

示例代码

调用 PhysicsUnit:GetNoCollisionPairUnitList 的示例。

lua
-- @runtime client
local physicsUnit = game:CreateUnit("PhysicsUnit", {})
local result = physicsUnit:GetNoCollisionPairUnitList()  -- 返回 Array
if result ~= nil then
    for index, item in ipairs(result) do
        print(index, item)
    end
end