主题
PhysicsUnit
概览
| 字段 | 值 |
|---|---|
| Kind | Unit · 单位 Unit |
| Realm | common |
继承关系
- Unit(4 属性 / 25 函数 / 6 事件)
继承成员
3 个来源 / 30 属性 / 43 函数 / 6 事件
- 来自 BasePart(23 属性 / 9 函数)
- 属性:
CFrame、PivotOffset、Position、Rotation、Scale、Size、ModelAlpha、ModelVisible、CastShadow、ModelColor1、ModelColor2、ModelColor3、ModelColor4、SkinId、UseCustomAppearance、CustomAppearanceId、OcclusionType、AssemblyRootPriority、AssemblyLinearVelocity、AssemblyAngularVelocity、AssemblyMass、AssemblyCenterOfMass、IsStaticOptimization - 函数:
IsNetworkOwnerSide、GetNetworkOwner、SetNetworkOwner、IsWeldConstraintRoot、IsWeldConstraintChild、GetWeldConstraintRootId、GetWeldConstraintId、GetConnectedUnits、SyncRenderToPhysics
- 属性:
- 来自 SpaceUnit(3 属性 / 9 函数)
- 来自 Unit(4 属性 / 25 函数 / 6 事件)
- 属性:
AssetId、Name、Desc、Parent - 函数:
ClearAllChildren、GetChildren、GetDescendants、IsAncestorOf、IsDescendantOf、FindFirstAncestor、FindFirstAncestorWhichIsA、FindFirstAncestorOfClass、FindFirstChild、FindFirstChildWhichIsA、FindFirstChildOfClass、HasChildren、GetChildCount、GetChildAtIndex、SetAttribute、GetAttribute、GetAllProps、Clone、IsA、Destroy、GetPropertyChangedSignal、GetAttributeChangedSignal、FindFromPath、GetFullPath、GetDebugId - 事件:
ChildAdded、ChildRemoved、DescendantAdded、DescendantRemoving、AncestryChanged、Destroying
- 属性:
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 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ModelBindParent | Bool | false | 是否让渲染模型跟随父节点的变换。 |
PhysicsMeshId | String | official://mesh/59268 | 用于物理碰撞检测的网格资源 ID。 |
BodyType | Int | Enums.BodyType.Dynamic | 物理类型,决定该物理单元的模拟方式。 |
PhysicsActive | Bool | true | 是否启用物理模拟。 |
CollisionGroup | String | "" | 该物理单元所属的碰撞组名称。 |
CanCollide | Bool | true | 是否参与物理碰撞,关闭后物体将穿透其他物体 |
CanTouch | Bool | true | 控制该物理单元是否能够被其他单元触发碰撞事件。 |
CanTrigger | Bool | true | 控制该物理单元是否能够触发其他单元的碰撞事件。 |
Mass | Float | 10 | 物理单元的质量。 |
Massless | Bool | false | 是否将物理单元视为无质量。 |
CustomPhysicalProperties | PhysicalProperties | - | 自定义物理材质属性,可覆盖默认的物理参数。 |
CenterOfMass | Vector3 | [0, 0, 0] | 物理单位的质心位置,相对于物体自身的局部坐标系。 |
GravityEnabled | Bool | true | 是否对该物理单元应用重力。 |
UseIndividualGravity | Bool | false | 是否使用自定义重力,而非全局重力。 |
IndividualGravityValue | Vector3 | [0, -9.8, 0] | 当 UseIndividualGravity 为 true 时,物理单位使用的自定义重力加速度。 |
LinearDamping | Float | 0 | 线速度阻尼系数,用于减缓物体的移动速度。 |
AngularDamping | Float | 0 | 角速度阻尼系数,用于减缓物体的旋转速度。 |
AngularVelocity | Vector3 | [0, 0, 0] | 物理单位的角速度,表示物体绕各轴的旋转速率。 |
LinearVelocity | Vector3 | [0, 0, 0] | 物理单位的线速度,表示物体在三维空间中的移动速度。 |
Climbable | Bool | false | 玩家角色是否可以攀爬此物体,仅对静态(Static)物体生效 |
CanQuery | Bool | true | 是否参与空间射线检测(Raycast、Spherecast 等),关闭后射线将穿透此物体 |
关联类型
事件 (4)
OnCollisionEnter
签名:OnCollisionEnter(otherUnit: Unit) 触发:local
当 PhysicsUnit 与其他单位发生碰撞接触时触发的事件。事件触发时,参数 otherUnit 为与该 PhysicsUnit 发生碰撞的另一个单位实例。
| 回调参数 | 类型 | 说明 |
|---|---|---|
otherUnit | Unit | 与之发生碰撞的另一个物体 |
示例代码
监听编辑器动态物体开始碰撞
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 解除碰撞的另一个单位实例。
| 回调参数 | 类型 | 说明 |
|---|---|---|
otherUnit | Unit | 结束碰撞的另一个物体 |
示例代码
监听编辑器动态物体结束碰撞
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
物理单元与其他对象发生碰撞并开始接触时,在本地端触发该事件。
| 回调参数 | 类型 | 说明 |
|---|---|---|
info | CollisionCallbackInfo | 碰撞回调信息 |
示例代码
监听 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
物理单元与其他对象结束碰撞接触时,在本地端触发该事件。
| 回调参数 | 类型 | 说明 |
|---|---|---|
info | CollisionCallbackInfo | 碰撞回调信息 |
示例代码
监听 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
添加一个允许与当前物理单位发生碰撞的碰撞组。
| 参数 | 类型 | 说明 |
|---|---|---|
groupName | String | 要加入的碰撞组名称 |
返回值 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
从当前物理单位的允许碰撞列表中移除指定碰撞组。
| 参数 | 类型 | 说明 |
|---|---|---|
groupName | String | 要移除的碰撞组名称 |
返回值 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)
endApplyForceToCenterOfMass
签名:ApplyForceToCenterOfMass(force: Vector3) -> void
在物理单位的质心处施加一个力。
| 参数 | 类型 | 说明 |
|---|---|---|
force | Vector3 | 世界空间中的力向量 |
返回值 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
在物理单位的局部坐标位置施加一个力。
| 参数 | 类型 | 说明 |
|---|---|---|
force | Vector3 | 世界空间中的力向量 |
localPosition | Vector3 | 物体局部空间中的施力点坐标 |
返回值 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
在物理单位的世界坐标位置施加一个力。
| 参数 | 类型 | 说明 |
|---|---|---|
force | Vector3 | 世界空间中的力向量 |
worldPosition | Vector3 | 世界空间中的施力点坐标 |
返回值 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
在物理单位上施加一个力矩,使其绕质心旋转。
| 参数 | 类型 | 说明 |
|---|---|---|
torque | Vector3 | 各轴方向的力矩大小 |
返回值 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
在物理单位的质心处施加一个冲量,瞬间改变物体的速度。
| 参数 | 类型 | 说明 |
|---|---|---|
impulse | Vector3 | 冲量向量,方向和大小决定瞬时速度变化 |
返回值 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
在物理单位的局部坐标位置施加一个冲量。
| 参数 | 类型 | 说明 |
|---|---|---|
impulse | Vector3 | 冲量向量 |
localPosition | Vector3 | 物体局部空间中的冲量施加点坐标 |
返回值 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
在物理单位的世界坐标位置施加一个冲量。
| 参数 | 类型 | 说明 |
|---|---|---|
impulse | Vector3 | 冲量向量 |
worldPosition | Vector3 | 世界空间中的冲量施加点坐标 |
返回值 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
获取物理单位上指定世界坐标位置的速度。
| 参数 | 类型 | 说明 |
|---|---|---|
position | Vector3 | 要查询速度的世界空间坐标点 |
返回值 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
添加一个不碰撞的单位对,使当前物理单位与目标单位之间不发生碰撞。
| 参数 | 类型 | 说明 |
|---|---|---|
targetUnit | SpaceUnit | 要互不碰撞的目标单位 |
返回值 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
移除一个不碰撞的单位对,恢复当前物理单位与目标单位之间的碰撞。
| 参数 | 类型 | 说明 |
|---|---|---|
targetUnit | SpaceUnit | 要恢复碰撞的目标单位 |
返回值 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<SpaceUnit>
获取与当前物理单位不碰撞的所有单位列表。
返回值 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