Unity Physics for DOTS 样例项目详解:EntityComponentSystemSamples 中 PhysicsSamples 的场景指南、目录结构与实现剖析
【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples
本文基于仓库中 PhysicsSamples/README.md 展开,系统梳理 Unity Physics(DOTS 版物理引擎)官方样例工程:覆盖 46 个演示场景的完整清单、Game/Scene 窗口的操作与调试显示方式、场景编号与仓库目录的对应关系,并结合同仓库源码剖析碰撞体运行时修改、立即模式物理步进等关键实现,帮助你在 Unity 6.2 环境下快速上手并深入理解 ECS 物理的 Authoring/System 工作流。
项目定位与运行环境
PhysicsSamples是 EntityComponentSystemSamples 仓库中专注于 Unity Physics for DOTS 的 Unity 工程。仓库主页 README.md 明确说明:本仓库中的样例工程基于 Unity 6.2,并使用Entities、Netcode、Physics、Entities.Graphics四个包的 1.4 系列版本。
从 PhysicsSamples/Packages/manifest.json 可以看到具体的依赖锁定:
| 包 | 版本 | 作用 |
|---|---|---|
com.unity.entities | 1.4.3 | ECS 框架核心 |
com.unity.entities.graphics | 1.4.16 | ECS 渲染桥接(Hybrid Renderer) |
com.unity.physics | 1.4.3 | Unity Physics 物理引擎 |
com.unity.render-pipelines.universal | 17.2.0 | URP 渲染管线 |
com.unity.inputsystem | 1.14.2 | 新输入系统 |
同时 manifest 中声明了"testables": ["com.unity.physics"],意味着该工程内置了针对 Unity Physics 包的 PlayMode 测试套件(位于PhysicsSamples/Assets/Tests/目录,包含 900 余个文件)。
从源码结构看,工程用 UnityPhysicsSamples.ASMDEF 定义统一程序集,并通过 csc.rsp 配置编译器参数,保证样例代码在 Burst/AOT 环境下的一致编译行为。
演示场景的通用操作方式
README 中Controls一节给出了所有演示场景在Game 窗口下的统一交互约定:
- 鼠标弹簧(Mouse spring):按住左键拖动——把选中的物理实体像弹簧一样拉拽,释放后由物理求解器产生回弹;
- 相机旋转(Camera rotate):按住右键拖动;
- 相机平移(Camera move):W、A、S、D 键。
这套约定由公共输入脚本驱动,公共输入动作定义在 PhysicsSamples/Assets/Common/InputActions.inputactions,输入采集逻辑见 DemoInputGatheringSystem.cs。
调试显示:Scene 视图与 Game 视图的差异
这是 README 中一个容易被初学者忽略的要点:许多演示(如 Query 系列的 ray cast、distance cast 等)会把额外信息以 debug gizmo 的形式绘制在 Editor 的Scene视图中,而不是Game视图。因此调试时要同时关注两个窗口。README 原表对比如下:
| Scene view(调试 Gizmo 显示在这里) | Game view(实际渲染画面) |
|---|---|
这一行为与 ReleaseNotes 中记录的一处修复相呼应:QueryTester.cs(用于 3a/3b/3c 查询演示)曾因调试绘制系统未正确调度导致调试线不显示,修复说明强调:任何使用PhysicsDebugDisplaySystem绘制能力的系统,必须调度在PhysicsDebugDisplayGroup内。这解释了为什么调试显示依赖 Scene 视图的 Editor 绘制管线,而不是 Game 视图的渲染输出。
完整场景清单
README 的核心是一张 46 行的场景总表,按Hello World / Setup / Query / Joints / Modify / Use Case六大类组织,每行标注场景名、描述、难度(Introductory / Intermediate / Advanced)与演示截图。以下为完整继承的清单(图片路径已转换为本仓库相对路径):
| Category | Scene | Description | Level | Demo |
|---|---|---|---|---|
| Hello World | Hello World.unity | Introductory scene for rigid body setup | Introductory | |
| Hello World | SphereAndBoxColliders.unity | Basic colliders | Introductory | |
| Hello World | GravityWell.unity | Introductory scene | Introductory | |
| Setup | 2a1. Collider Parade - Basic.unity | Demo showing various shapes for collision detection | Introductory | |
| Setup | 2a2. Collider Parade - Advanced | Demo showing various shapes for more advanced collision detection | Introductory | |
| Setup | 2b1. Motion Properties - Mass.unity | Demo showing how to explicitly set mass properties using custom (yellow) and built-in (grey) authoring components | Introductory | |
| Setup | 2b2. Motion Properties - Velocity.unity | Setting initial linear and angular velocities | Introductory | |
| Setup | 2b3. Motion Properties - Damping.unity | Demo showing the effect of linear and angular damping | Introductory | |
| Setup | 2b4. Motion Properties - Gravity Factor.unity | Demo showing the effect of per body gravity multipliers | Introductory | |
| Setup | 2b5. Motion Properties - Center of Mass.unity | Demo showing the effect of overriding center of mass | Introductory | |
| Setup | 2b6. Motion Properties - Inertia Tensor.unity | Demo showing the effect of overriding inertia tensor | Introductory | |
| Setup | 2b7. Motion Properties - Smoothing.unity | Demo showing the effect of interpolation and extrapolation | Introductory | |
| Setup | 2c1. Material Properties - Friction.unity | Showing effect of different friction material values | Introductory | |
| Setup | 2c2. Material Properties - Restitution.unity | Showing effect of different restitution values | Introductory | |
| Setup | 2c3. Material Properties - Collision Filters.unity | Showing effect of different collision filters | Introductory | |
| Setup | 2d1. Events - Triggers.unity | Demo demonstrating the usage of triggers | Introductory | |
| Setup | 2d2. Events - Contacts.unity | Showing effect of different contacts | Introductory | |
| Query | 3a. All Hits Distance Test.unity | Demo showing results of distance queries between multiple colliders | Introductory | |
| Query | 3b. Cast Test.unity | Demo showing the results of collider casting and ray casting | Introductory | |
| Query | 3c. Closest Hit Distance Test.unity | Demo showing results of distance queries | Introductory | |
| Query | 3d. Custom Collector.unity | Demonstration of raycast | Introductory | |
| Joints | 4a. Joints Parade.unity | Demo showing a range of joint types | Introductory | |
| Joints | 4b. Limit DOF.unity | Showing effect of limiting degrees of freedom | Introductory | |
| Joints | 4c1. All Motors Parade.unity | Demo showing different motors | Introductory | |
| Joints | 4c2. Position Motor.unity | Demo showing position motor | Introductory | |
| Joints | 4c3. Linear Velocity Motor.unity | Showing linear velocity motor | Introductory | |
| Joints | 4c4. Angular Velocity Motor.unity | Demonstrating angular velocity motor | Introductory | |
| Joints | 4c5. Rotational Motor.unity | Demonstrating rotational motor | Introductory | |
| Joints | 4d. Ragdolls.unity | Obligatory stack of ragdolls demo | Introductory | |
| Joints | 4e. Single Ragdoll.unity | GameObject ragdoll for Unity Physics (left) and built-in physics (right), created using the Ragdoll Wizard | Introductory | |
| Modify | 5a. Change Motion Type.unity | Demo showing change of motion type | Introductory | |
| Modify | 5b. Change Box Collider Size.unity | Demonstrating runtime change of collider size | Introductory | |
| Modify | 5c. Change Collider Type.unity | Demonstrating change of collider type | Introductory | |
| Modify | 5d. Change Velocity.unity | Demo showing change of velocity | Introductory | |
| Modify | 5e. Kinematic Motion.unity | Demo showing kinematic motion in combination with dynamic objects | Introductory | |
| Modify | 5f. Change Surface Velocity.unity | Demo showing change of surface velocity | Introductory | |
| Modify | 5g1. Change Collider Material - Bouncy Boxes.unity | Demo showing effect of unique prefab instantiation with collider material changes | Intermediate | |
| Modify | 5g2. Unique Collider Blob Sharing.unity | Demo showing effect of instantiating prefabs during runtime, making collider blobs unique and sharing collider blob data | Advanced | |
| Modify | 5g3. Runtime Collider Creation.unity | Create mesh colliders during runtime | Advanced | |
| Modify | 5g4. Runtime Collision Filter Modification.unity | Modify collision filters during runtime | Advanced | |
| Modify | 5g5. Modify Collider Geometry.unity | Modify collider geometry during runtime | Advanced | |
| Modify | 5h. Change Scale.unity | Demo showing scale change of entities | Introductory | |
| Modify | 5i. Apply Impulse.unity | Demo showing application of impulses | Introductory | |
| Modify | 5j. Modify Broadphase Pairs.unity | Filter out collision by explicitly deleting pairs from broad phase | Advanced | |
| Modify | 5k. Modify Contact Jacobians.unity | Modify the results of contact generation to produce special effects | Advanced | |
| Modify | 5l. Modify Narrowphase Contacts.unity | Add new user contacts to simulation pipeline | Advanced | |
| Use Case | 6a. Character Controller.unity | Use case demo showing a rudimentary FPS character controller | Intermediate | |
| Use Case | 6b. Pool.unity | Demonstration of calling immediate mode physics | Intermediate | |
| Use Case | 6c. Planet Gravity.unity | Performance demo of asteroids around a planet using SP/HP | Introductory | |
| Use Case | 6d. Raycast Car.unity | Use case demo showing a set of vehicle behaviors | Intermediate |
场景编号与仓库目录的对应关系
值得注意的一点:README 表格中的编号(1–6 大类)是演示教学顺序,而仓库目录是按 ReleaseNotes.md 中 1.2.0 版本提到的 "Reorganized the samples, with cleanup of various samples' code and scenes" 重新组织后的主题目录,两者并非一一对应。对照 PhysicsSamples/Assets 的实际结构,映射关系大致如下:
| README 分类 | 实际场景所在目录 | 说明 |
|---|---|---|
| Hello World(1) | PhysicsSamples/Assets/1. Hello World/ | 含HelloWorld.unity、SphereAndBoxColliders.unity,刚体字母由Letter.prefab与Alphabet.fbx构成 |
| Hello World(1,GravityWell) | PhysicsSamples/Assets/2. Gravity Well/ | GravityWell.unity,配套 GravityWellSystem.cs 演示自定义力场 System |
| Setup - Collider Parade(2a) | PhysicsSamples/Assets/3. Collision Geometry/ | 基础/进阶碰撞形状演示 |
| Setup - Motion Properties(2b) | PhysicsSamples/Assets/4. Motion Properties/ | Mass、Velocity、Damping、Gravity Factor、Center of Mass、Inertia Tensor、Smoothing 共 7 个子场景,配套PhysicsMassBehaviourAuthoring.cs、MotionSmoothingAuthoring.cs等 Authoring 脚本 |
| Setup - Material Properties(2c) | PhysicsSamples/Assets/5. Material Properties/ | 摩擦、弹性、碰撞过滤器 |
| Setup - Events(2d) | PhysicsSamples/Assets/6. Events/ | Triggers(含 Change Material、Force Field、Gravity Factor、Portals 四个子场景)与 Contacts/Collisions |
| Query(3) | PhysicsSamples/Assets/7. Queries/ | 距离查询、Collider Cast、Custom Collector,配套CastQueries.prefab、ClosestDistanceQueries.prefab |
| Joints & Motors(4) | PhysicsSamples/Assets/8. Joints and Motors/ | 关节类型巡礼、Limit DOF、五种 Motor、Ragdoll |
| Modify(5) | PhysicsSamples/Assets/9. Modify/ | 13 个运行时修改演示,脚本集中于9. Modify/Scripts/ |
| Use Case(6) | 10. Immediate Mode、11. Planet Gravity、12. Raycast Car、13. Character Controller | Pool(立即模式)、行星重力性能演示、射线车、FPS 角色控制器各占一个独立编号目录 |
另外,每个演示目录下的实际.unity场景文件大多放在子目录(如Subscenes/、Raycast Car/Raycast Car.unity),主目录的.unity是外层编排场景——这是 DOTS 子场景(Subscene)的典型组织方式。
源码级实现剖析
运行时修改碰撞体:Authoring + Blob 数据的分工
Modify系列是本工程难度跨度最大的部分(Introductory 到 Advanced),其脚本都集中在 PhysicsSamples/Assets/9. Modify/Scripts/,其中能直接体现 Unity Physics 核心机制的几个例子:
ColliderBakeTransformAuthoring.cs(公共基础设施,见 Common/Scripts):支撑5g5. Modify Collider Geometry演示。从源码可以看到其字段设计:Translation、Rotation、Scale、ShearXY/XZ/YZ三组剪切向量、AnimationDuration动画周期,以及防漂移机制(DriftPrevention、DriftErrorThreshold = 0.05f)。Baker 把这些参数烘焙为 ECS 组件ColliderBakeTransform,并保存BlobAssetReference<Unity.Physics.Collider> OriginalCollider与PostTransformMatrix OriginalPostTransformMatrix——这正是 README 表格中"Modify collider geometry during runtime"的底层手段:通过Collider.BakeTransform对碰撞体几何施加仿射变换(旋转、平移、缩放、剪切),实现循环形变动画。组件里还定义了ICleanupComponentData(SaveColliderBlobForDisposal)用于子场景销毁时正确释放碰撞体 Blob,这一点在 ReleaseNotes.md 的 1.3.0 修复记录中得到了印证(修复了ColliderBakeTransformSystem的内存泄漏)。ChangeColliderBlobAuthoring.cs/ChangeColliderTypeAuthoring.cs/ChangeBoxColliderSizeAuthoring.cs:分别对应5g1 Bouncy Boxes、5c. Change Collider Type、5b. Change Box Collider Size,展示"修改 BlobAssetReference 指向的数据"与"替换组件引用"两种运行时改碰撞体的路径。ModifyBroadphasePairsBehaviour.cs、ModifyContactJacobiansBehaviour.cs、ModifyNarrowphaseContactsBehaviour.cs:对应三个 Advanced 级演示,展示在 broadphase 中显式删除碰撞对、修改接触雅可比、向仿真管线注入用户接触这几种"干预物理管线"的高级用法。
立即模式物理步进:Pool 演示的支撑工具
6b. Pool演示("Demonstration of calling immediate mode physics")依赖 ImmediatePhysicsWorldStepper.cs。从源码看,它是一个IDisposable结构体,内部持有独立的SimulationContext(及条件编译下的HavokSimulationContext),Create()工厂方法显式声明"不适合在 ECS job 中作为字段使用"——因为它在主线程上立即运行一次物理步进,与正常 ECS 系统调度解耦。这类"旁路世界"用法在 ReleaseNotes.md 0.10.0-preview 条目中还有更完整的说明:Tests/MultipleWorlds下的 Animation 场景用独立PhysicsWorld模拟非关键动画体(马尾、剑鞘),ClientServer 场景则演示了服务端/客户端双物理世界的 ghost body 驱动模式。
公共基础设施目录
PhysicsSamples/Assets/Common/ 汇集了所有演示共享的组件与工具,值得单独浏览:
Scripts/CameraControl.cs、CameraSmoothTrack.cs:实现 READMEControls一节的相机旋转/平移约定;Mouse/目录:鼠标弹簧选择(Mouse Pick),ReleaseNotes 中多次提到其演进(如MouseHoverAuthoring支持渲染组件位于子实体的情况,并在4d. Ragdolls场景中启用);EntityTracker.cs、SceneCreationSystem.cs、GridSpawner.cs:演示实体生命周期追踪、运行时场景创建与网格生成;Tests/子目录:演示工程内嵌的行为验证工具(SimulationValidationAuthoring组件用于确认关节按预期工作、刚体能否静止)。
自定义 Authoring 体验的自动导入
根据 ReleaseNotes.md 的 1.0.0 条目,围绕PhysicsBodyAuthoring/PhysicsShapeAuthoring组件的Custom Physics Authoring样例已从包 API 中剥离,改由 Unity Physics 包以 Sample 形式自动导入,落在 PhysicsSamples/Assets/Samples/ 下的Unity Physics/<包版本>/Custom Physics Authoring。仓库中该目录当前对应1.4.3版本;ReleaseNotes 同时提醒:升级 Unity Physics 包后,需在 Package Manager 的Samples页签重新导入新版本样例,并手动清理旧版本目录。
PlayMode 测试套件
PhysicsSamples/Assets/Tests/ 是规模可观的验证层(223 个.unity场景、95 个.cs脚本),目录涵盖 JointTest(Hinge、Prismatic、LimitedHinge 等)、Stacking、Character、CharacterController、MultipleWorlds、Performance、SchedulerTest、StaticOptimize、StreamingStressTest 等。ReleaseNotes 显示多个关节演示场景已通过SimulationValidationAuthoring接入 PlayMode 自动验证,即演示与回归测试共用同一套验证基础设施。
版本演进要点
PhysicsSamples/ReleaseNotes.md 记录了从 2019 年0.0.1-preview到当前1.3.0+的完整演进,其中对使用者最有价值的几个节点:
- 1.3.0:Joints Parade 的
BreakJoint1MaxImpulse 从 (10,10,10) 调为 (2,2,2);新增Modify Collider Geometry演示与ColliderBakeTransformAuthoring组件;自定义 Authoring 组件的 Motor 支持 spring/damping 字段。 - 1.2.0:样例整体重组织与代码清理(即上文目录重排的依据)。
- 1.1.0:新增
4e. Single Ragdoll(用内置 Ragdoll Wizard 创建的 GameObject 布娃娃,左右对比 DOTS 物理与内置物理);新增运行时创建 Mesh Collider 的三个MeshCollider.Create重载 API(支持UnityEngine.Mesh、MeshData、MeshDataArray);新增Force Unique Collider Authoring组件与5g2. Unique Collider Blob Sharing、5g4. Runtime Collision Filter Modification演示。 - 1.0.0:Custom Physics Authoring 样例改为包样例自动导入(见上节)。
更早版本(0.x 系列)还记录了 Character Controller 的隧道检测修复、ImmediatePhysicsWorldStepper引入、MultiWorld 演示等内容,对理解各演示的设计动机有帮助。
上手路径建议
- 环境准备:用 Unity 6.2 打开
PhysicsSamples目录(manifest 锁定的包版本会由 Package Manager 解析),确认com.unity.physics1.4.3 正常解析。 - 按难度递进:从
1. Hello World(刚体基础)→3./4./5.的 Setup 类场景(碰撞形状、运动属性、材质)→7. Queries(查询与调试显示,注意 Scene 视图)→8. Joints and Motors→9. Modify(重点看 5g 系列的 Blob 修改)→10.–13.的四个 Use Case。 - 读源码对照:每个演示目录下都有同名 Authoring/Behaviour 脚本,按"Authoring(编辑器烘焙)→ Baker → 组件 → System(运行时修改)"的链路阅读,可把 README 表格中每个演示对应到具体 API 调用。
- 扩展学习:仓库同时提供了 Dots101/Physics101/ 入门工程(ActivationPlates、GravityWell、LaserSight、Pachinko 等小例子),README.md 主页将其与 Unity Physics 101 文档配套推荐;
PhysicsSamples内Assets/Tests/的验证场景也可作为回归测试范例参考。
参考路径索引
- 核心文档:PhysicsSamples/README.md、PhysicsSamples/ReleaseNotes.md、PhysicsSamples/TestRunnerOptions.json
- 依赖与工程配置:PhysicsSamples/Packages/manifest.json、PhysicsSamples/ProjectSettings/
- 演示场景:PhysicsSamples/Assets/1. Hello World/ 至 PhysicsSamples/Assets/13. Character Controller/
- 公共实现:PhysicsSamples/Assets/Common/Scripts/、PhysicsSamples/Assets/9. Modify/Scripts/
- 测试场景:PhysicsSamples/Assets/Tests/
- 演示截图与动图:PhysicsSamples/READMEimages/
【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考