
Chinese: 
♪ [音乐] ♪
[旁白] 欢迎来到 Unite Now，
我们将 Unity 呈现给您，不论身处何处
[STEVE] 嗨，我是 Steve Ewart，我想带你了解一下
DOTS Physics 软件包中的一些功能
作为一个简短的概述，我们将看看 Physics （物理）
和 DOTS 到底意味着什么
在介绍 Package Manager 中提供的
Unity Physics 软件包和
Havok Physics for Unity 软件包之前
我还想谈谈一些常见的用例
在这些用例中，我们可以操纵物理模拟来
获得车辆效果、布娃娃
和角色控制器
在 DOTS 中，我们所说的物理是什么意思？
我认为值得强调的是，已经有一些在线视频
特别是去年在 Unite Copenhagen
录制的综述类讲座
这些将为本次讲座中讨论的一些内容
提供一个背景

English: 
♪ [MUSIC] ♪
[NARRATOR] Welcome to Unite Now,
where we bring Unity to you,
wherever you are.
[STEVE] Hi. My name is Steve Ewart,
and I wanna take you through
some of the functionality
in the DOTS Physics packages.
Just as a quick overview,
we'll look at exactly what we mean
by Physics and DOTS.
Before looking at the Unity
Physics package,
and the Havok Physics
for Unity package
that are available
in the Package Manager now,
I also wanna touch on
some common use-cases
where we can manipulate
the Physics simulations
to get vehicle effects
and ragdolls,
and Character Controllers.
What do we mean by Physics in DOTS?
I think it's worth highlighting
some of these videos
that are already available online,
particularly overview sessions
that were recorded
in Unite Copenhagen, last year.
These will provide a context
for some of the things discussed
in this session.

English: 
So, what do I mean by
"Physics in DOTS?"
Well, we need to provide
a data structure that can represent
the physical nature
of the physics simulation
with dynamic and static bodies,
the joints that might connect them,
and the forces that we
wanna apply to those bodies.
It also is about providing an API
so that we can query
that physics world,
whether it's a Raycast,
a Cast Collider,
or some distance query about
how far apart two objects are.
And also with the data,
and the query API,
we also want to provide
a simulation-appropriate
collision response,
and all of the information that you
can get from that simulation
so that you can control it
in exactly the way you want.
It's worth highlighting that the
Unity Physics package provides
the data representation,
the query API,
and also a simulation backend.
The Havok Physics for Unity package
implements a different simulation
back-end with a different focus.

Chinese: 
那么，我所说的“DOTS 中的物理”是什么意思？
我们需要提供一个数据结构
它可以代表物理模拟的物理本质
包括动态和静态物体，连接它们的关节
以及我们想对这些物体施加的力
它还提供了一个 API
这样我们就可以查询这个物理世界
无论是射线投射，投射碰撞体
还是一些关于两个物体之间距离的查询
此外，有了数据和查询 API
我们还希望提供一个
适合模拟的碰撞响应
以及可从该模拟中获得的所有信息
这样，你可以按照所需的方式来控制它
值得强调的是，Unity Physics 软件包提供了
数据表示、查询 API
以及模拟后端
Havok Physics for Unity 软件包
实现了一个不同的模拟后端，侧重点不同

English: 
Unity Physics Simulation
backend is geared
towards easy rollback
and networking scenarios.
The Havok Physics
for Unity Simulation backend
is geared towards larger Scenes
where deactivation of bodies
is necessary to get
the maximum performance,
and also a cache-based approach
whereby you get
a much more elaborate
friction model.
Let's look at Unity Physics
for the moment,
and we wanna touch on
a Conversion Example,
and also look at some of the
Feature Highlights.
Just before we look at the
Conversion Example in the Editor,
I wanna highlight the pipeline.
Once you've setup your data
in the Editor
with the Authoring Data,
it goes to the
Game Conversion pipeline
into the ECS Data,
the component data.
And then there are
three systems that are part
of the Unity Physics package:
the Build Physics World
takes out ECS data and converts it
into runtime format

Chinese: 
Unity Physics 模拟后端面向
简单的回滚和网络场景
Havok Physics for Unity 模拟后端
面向的是更大的场景，在这些场景中
为了获得最高性能，必须停用某些物体
同时，它也是一种基于缓存的方法
使你可以得到一个更复杂的摩擦模型
我们先介绍一下 Unity Physics
我们采用一个转换示例
同时也了解一些功能亮点
在编辑器中查看转换示例之前
我想强调一下管线
一旦用创作数据在编辑器中
设置好你的数据
这些数据就进入了游戏转换管线
进入 ECS 数据，组件数据
Unity Physics 软件包含有三个系统
Build Physics World 取出 ECS 数据
并将其转换成更适合

Chinese: 
大量随机访问的运行时格式
然后，Step Physics System 获取
运行时物理数据，并步进模拟
寻找碰撞并做出适当的响应
一旦我们有了这些新的方向和位置
Export Physics World 系统就会将物理数据
即下一帧的新物理数据
转换回组件数据
这种设置提供了灵活性，但它确实有些影响
我们将在查看用例时看到其中的一些影响
在这个转换的示例中，我想考虑
一个简单的物理场景，其中
我们有多个 GravityWell（重力井）在移动
大量的动态物体受到
所有这些 GravityWell 的影响
因此，我们将在游戏对象中进行设置
然后来看一个场景，其中
我们可以转换那些游戏对象
不仅仅通过数据表示
还包括到 ECS 中的逻辑表示

English: 
that's more appropriate
for large amounts of random access.
The Step Physics System then
takes this runtime Physics data
and steps the simulation forward
looking for collisions
and responding appropriately.
Once we have these
new orientations and positions,
the Export Physics World system
converts the Physics data,
this new Physics data
for the next frame, back
into the component data.
This setup provides flexibility
but it does have implications,
and we'll see some of those
when we look at the use cases.
For this Conversion Example,
I wanna consider
a simple Physics scenario
where we have
multiple GravityWells
moving around,
and a large number
of dynamic bodies
that are being affected
by all of those GravityWells.
So we'll look at it, setting it up
in GameObjects,
and then we'll look at a scenario
where we can have
those GameObjects converted,
not just with the
data representation
but also the logic
representation into ECS.

Chinese: 
然后，我们从纯 ECS 的角度来看看同样的场景
这是一个非常简单的场景，有一个静态的地板
上面具有原始的盒型碰撞体类型
我们还有一些动态的球体
它们具有一个刚体、质量和一个球形碰撞体
当我按下 Play 时，它们会弹起，当然
你可以看到球和地板之间的
各种交互
所有物理的对象都在这个
更高级别的游戏对象节点下
当然，我可以把所有对象都转换成 ECS
现在我们在 Unity Physics 中模拟
而不是在最初的游戏对象 Physics 中
这很简单，这些只是对象
它们被转换成
带有组件数据的实体
但是这个特定的例子
没有逻辑，没有控制
所以，我想让转到一个更详细的演示

English: 
Then we look at the same scenario
from a perspective of pure ECS.
This is a very simple Scene.
We have a static floor
with the original
Box Collider type on it
and we have a number of spheres
which are dynamic,
they've got a Rigidbody and a mass
and a Sphere Collider.
And when I press "play,"
they of course, bounce.
You can see
the various interactions
between the balls and the floor.
And everything
that is physical is underneath
this higher level GameObjects node.
And of course, I can just
convert everything over
into ECS, and now we're simulating
in Unity Physics
rather than in the original
GameObject Physics.
Now that's simple enough,
these are just objects,
they're being converted into
Entities with component data.
But there's no logic,
there's no control
going on in this
particular example.
So, I want us to jump
to a more detailed demo

Chinese: 
试图操控这些球体
在这个特定的例子中，我们移除了地板
这些物体仍然在那里
球体仍然在场景中
我只是额外添加了一个生成器
它将再添加 250 个这样的球体
我还有一个 GravityWell
抱歉，一系列 GravityWell
它们有一种特殊的力量，会把物体拉向它们
所以我们已经有了关联的逻辑
现在，也有了与此关联的脚本
我们可以转去看看脚本
这里，对于每个 dynamicBody 都很简单
我们将向 GravityWell 的中心
施加一个爆炸力
我们运行...
可以看到所有的物体都产生了
GravityWell 在旋转
物体被吸引向 GravityWell
现在，同样，当转换物体时...

English: 
which actually is trying
to manipulate those spheres.
In this particular case,
we've removed the floor
and these objects are still there,
the spheres are still there
in the Scene.
And I just added
for good measure a spawner,
which is going to throw in
another 250 of these.
What I've also got
is a GravityWell,
or a series of GravityWells,
sorry, which
have a particular strength and
will draw the bodies towards them.
So we've actually got the logic
associated with this.
There's actual scripts
associated with this now.
We can jump in and see that script.
Here, it's just a simple
for each dynamicBody
and we're going to apply
an explosive force
towards the center
of the GravityWell.
Let's run that...
and you can see that all
the objects got spawned,
the GravityWells are rotating
and the bodies are being attracted
towards those GravityWells.
Now, in the same way,
as we converted the objects...

English: 
in the last example,
if I convert to Entity here
then they do nothing.
They're now converted
but they're floating through space
with no GravityWells,
forces being applied.
So what we need to do is
start trying to pull in the logic
into the conversion
pipeline as well.
This version of our Scene
is slightly different.
I've moved all
the convertible objects
under this Convertible Node
and now the convertible objects,
are going to include
the GravityWell.
Just to move towards
an ECS-style setup,
rather than having
the GravityWells
have all the logic
and all of the data.
We're actually gonna start
splitting up the GravityWells
into a component,
which just has the data,
the Strength and the Radius
of the GravityWell,
and we've moved all of the logic
under the Systems Node
where there's
a GravityWell system.

Chinese: 
在上一个例子中，如果我在这里转换为 Entity
那么它们什么也不做
它们现在被转换了，但是它们漂浮在空中
因为没有 GravityWell，没有施加力
因此，我们需要做的是开始尝试
将逻辑也拉入转换管线
我们这个版本的场景略有不同
我已经将所有可转换对象移动到这个
Convertible 节点下，现在这些可转换对象
将包括 GravityWell
这只是为了满足 ECS 样式的设置
而不是让 GravityWell 拥有
所有的逻辑和所有的数据
我们实际上要开始将 GravityWell
分割成一个组件，它只有 GravityWell 的
数据、强度和半径
我们已经将所有的逻辑移到 Systems 节点下
那里有 GravityWell 系统

Chinese: 
所以这个模拟看起来完全一样
物体被生成，它们在世界中移动
现在，当我转到 Convertible，并转换到 Entity
逻辑也将转换
我们现在运行在 ECS 中，在 Unity Physics 中
并进行模拟，行为略有不同
这只是一个表象，但是我们已经转换了
物体的逻辑和表示
让我们简要地看一下这意味着什么
然后我们回到 Visual Studio
现在看看我们的组件
以前我们只有一个 MonoBehavior
只有一个 Update() 遍历所有物体
现在，我们有了一个组件，里面包含数据
和 GravityWell 系统
它获取所有的 GravityWell
然后遍历每个 dynamicBody
并将每个 GravityWell 应用到每个物体上

English: 
So this simulation
looks exactly the same;
objects are spawned
and they move through the world.
But now when I go to Convertible,
and convert to Entity,
the logic is also converted.
So, we're now running in ECS,
we're running in Unity Physics
and doing simulation,
the behavior is slightly different.
That's going to be just a fact,
but we've converted the logic
and the representation
of the bodies.
Let's briefly have a look at
what that entails,
and we go back to Visual Studio.
Looking at our components now,
where previously we had
a single MonoBehavior
with a single Update() flipping
through all the bodies.
Now we've got a component
which has got the data in it
and the GravityWell
system, which is
grabbing all of the GravityWells,
and then looping through
each dynamicBody
and applying each GravityWell
to each body.

Chinese: 
现在，同样值得思考的是
有两个信息源
每个游戏对象有一个变换
有 GravityWell 的位置
当然，还有 GravityWell 的强度和半径
只要转换成 ECS，这都是一个
需要实现的非常有用的接口
在数据层面上，我们将 MonoBehavior 信息转换成
GravityWellComponent
一个 IComponentData，就在下面
在这个特定的例子中，因为我们希望
所有的数据都在一个位置，当我们在内存中遍历时
会将 transform.position 拉入到
IComponentData 中
因此，GravityWell 的全部信息都集中在一个位置
对于系统本身，就将逻辑转换成 ECS 而言
我们要实现一个 SystemBase

English: 
Now, it is also worth considering
that there are two sources
of information.
There's the transform,
the position of the GravityWell
on the GameObject,
and then of course,
there's the GravityWell's
Strength and Radius as well.
Whenever we're converting into ECS,
this is a very useful interface
to implement,
and on the data level, we convert
our MonoBehavior information
to a GravityWellComponent,
an IComponentData,
which is down here.
In this particular case
because we want all the data
in one place, as we go through
it in memory,
we're going to pull in
the transform.position
into the IComponentData,
so we have all the GravityWell
information in one place.
On the system itself, in terms of
converting this logic into ECS,
we are implementing a SystemBase.

English: 
These are effectively the queries
looking for the GravityWells,
and the dynamicBodies,
a little bit like
find objects of type.
And then in the OnUpdate section,
here is a little piece of code
that is grabbing the position
of the GravityWells
and putting them
into our Component each time.
And then this section, is using
all of those GravityWells
and looping through, and applying
that force in a similar way.
This version of the same demo
is entirely built
around ECS from the ground up.
Spheres use the newer Physics Shape
and Physics Body components
rather than the Collider
and the Rigidbody components
we used previously,
and the GravityWells simply have
the ComponentData exposed.
In this particular case,
you also see
the position in the UI
and you'll see why in a sec.
But the behavior's
exactly the same.

Chinese: 
这些实际上是查询
寻找 GravityWell 和 dynamicBodies
有点像查找特定类型的对象
然后在 OnUpdate 部分，这里有一小段代码
它抓取 GravityWell 的位置
每次都将它们放入我们的 Component 中
然后是这个部分，使用所有的 GravityWell
进行遍历，以类似的方式施加力
同一演示的这个版本完全是
围绕 ECS 从头开始构建的
Spheres 使用较新的 Physics Shape 和
Physics Body 组件，而不是之前的
Collider 和 Rigidbody 组件，GravityWell
只公开 ComponentData
在这个特定的例子中，你也可以在 UI 中
看到这个位置，马上就会知道为什么了
但是行为完全一样

English: 
There's no conversion going on
this time, but the bodies
are being simulated
in ECS and Unity Physics
and the GravityWells are being
manipulated in a similar way
with their systems.
Looking at the code
in Visual Studio,
again we can see we've just
got our IComponentData,
with Strength, Radius,
and Position as before,
and we use this attribute to create
the UI in the Unity Editor.
The pure ECS systems
are very similar.
The difference here being
we're starting to play
with things like ScheduleParallel,
which allows us
to run the simulation
in particular, this GravityWell
code, on multiple threads
for different blocks of bodies
to help performance,
and that's exactly why we want
to do this conversion
in the first place.
There is somewhat more code here,
however the performance difference
is worth it in the end.
These graphs show why we wanted
to move to ECS in the first place.
The green lines represent
the GameObject,

Chinese: 
这次没有进行转换，但是物体是
在 ECS 和 Unity Physics 中模拟
GravityWell 由其系统
以类似的方式操纵
在 Visual Studio 中查看代码
可以再次看到，我们使用了 IComponentData
和以前一样具有强度、半径和位置
我们使用这个属性在 Unity 编辑器中创建 UI
纯 ECS 系统非常相似
不同的是，我们使用了
像 ScheduleParallel 这样的技术
它允许我们在多个线程上运行模拟
特别是这个 GravityWell 代码
对物体分批并行处理
非常有助于提高性能
这正是我们要进行这种转换的原因
这里代码增加了一些，但是最终结果是
性能获得了提升
这些图表显示了我们最初为何要迁移到 ECS
绿线代表游戏对象

Chinese: 
GravityWell OnUpdate() 函数
以及整个框架的步骤
很明显，随着刚体数量的增加
橙色的 ECS 曲线会表现的更好
对于较少数量的刚体，在 ECS 端仍有些开销
但是我们会逐步减少这一开销
让我们来看看现有 Unity Physics
软件包中的一些功能亮点
以及我们将在未来几周
发布的版本
这个演示是我们的即时模式演示
它展示这个物理模拟
在接下来的 100 帧的效果
并突出显示了在以特定的方向
特定的力量击打母球后
球会行走的轨迹
这演示了模拟的确定性
球会沿着预测的路径运动
但是，帧速率是有问题的

English: 
both the GravityWell
OnUpdate() function
and the overall frame step.
It's very clear that as the number
of Rigidbodies increase,
the orange ECS lines scale
much, much better.
For smaller number of Rigidbodies,
there is still a slight overhead
on the ECS side, but we will be
reducing that over time.
Let's look at some
of the Feature Highlights
in the Unity Physics package
that's available now
and the versions
that we'll be releasing
in the next couple of weeks.
This demo is
our immediate mode demo.
It shows this physics simulation
being stepped 100 frames
into the future,
and highlights the trails
the balls would take
if the cue ball was hit
at a particular direction,
at a particular strength.
This illustrates the determinism
of the simulation
as the balls follow
the paths predicted.
However, frame rate
is questionable.

English: 
In the latest version,
that is no longer the case
and it's worth highlighting why.
The original setup
effectively did a full simulation
100 times into the future,
and that full simulation spawned
as many jobs as possible
to do all of the work,
and across as many
threads as possible.
For a smaller simulation,
the spawning of those jobs
might actually be more expensive
than the simulation itself.
So we've introduced
some stepping control.
The Thread Content
is really is that,
it's only a hint of the moment.
Unity Physics spawns jobs
on as many threads
as there are available.
Havok Physics does use
this Thread Count, though,
to limit the number
of threads it uses.
In future versions
of Unity Physics,
we'll be able to also limit
the number of threads used.
But right now, if you set
that Thread Content to 0
the simulation will end up
using only one thread,

Chinese: 
在最新版本中，情况不再如此
原因值得强调一下
最初的设置实际相当于对接下来的效果
进行了 100 次完全模拟
这种完全的模拟会产生尽可能多的作业
来完成所有任务
并且覆盖尽可能多的线程
对于较小的模拟，产生的这些作业
实际上可能比模拟本身开销更大
所以我们引入了一些步进控制
Thread Count Hint 实际上是
只是一个瞬间的提示
Unity Physics 在
尽可能多的线程上生成作业
Havok Physics 确实使用这个 Thread Count
来限制它使用的线程数量
在 Unity Physics 的未来版本中
我们还能限制的线程使用数
现在，如果你将 Thread Count Hint 设置为 0
模拟将只使用一个线程

English: 
become single-threaded,
and only spawn a single job
rather than many jobs
for all the smaller pieces of work.
This means all of the other threads
are free to do whatever you want
and it also means that you're
not having the overhead
of spawning many jobs.
Joints have been available
in the runtime from the beginning
but none of the previous demos
touched on them
so I want to
highlight them here now.
Connecting two Entities together,
the JointData holds
a frame of reference
in the space of each
of those Entities,
and in an array
of Constraint atoms.
Each atom can be Linear or Angular,
could have Min and Max limits
and work on one, two or three axes.
They can also have Stiffness
and Damping parameters.
And you can put these
Contraint atoms together,
to get whatever sort of joint
you want.
You could create custom Joints.
We do supply a number
of Joints out of the box
but they are just a combination
of these Constraint atoms.

Chinese: 
变成单线程，并且只产生一个作业
而不是为所有较小任务生成多个作业
这意味着所有其他线程不会受到任何影响
也意味着你没有生成许多
作业的开销
关节从一开始就运行时中就提供了
但是之前的演示都没有涉及到它们
所以我想在这里重点介绍
关节将两个实体连接在一起
JointData 保存每个实体的
空间中的参考系
以及一个约束原子数组
每个约束原子可以是直线或者旋转
其最小最大限制，工作在几个轴上（1-3）
还可以有刚度和阻尼参数
你可以把这些约束原子组合
实现任意种类的关节
你可以创建自定义关节
我们也确实提供了一些现成的关节
但它们不过是这些约束原子的组合

Chinese: 
例如，球窝关节实际上
是一个单一的线性约束原子，没有限制
工作在所有三个轴上，因此自由度
由参考系定义的特定点的
线性自由度
不允许在所有三个轴上移动
如果我们添加一个额外的角度约束
工作在两个轴上，并且没有限制
那么我们得到一个自由铰链
只能绕一个轴旋转
如果我们增加最小和最大角度限制
那么我们将得到一个受限铰链
通过这种方式，可以构建自定义关节
我们还彻底改造了命中收集器
以前，出于性能原因
你必须变换成命中信息
根据身体层次结构中特定形状
被击中的位置
这很困难，我们现在已经处理了所有的工作

English: 
For example,
a Ball & Socket Joint
is actually a single linear
Constrain atom with no limits
and working in all three axis,
so the degrees of freedom,
the linear degrees of freedom
at a particular point
defined by the reference frames
are not allowed to move
on all three axis.
If we add an extra
angular Constraint
that works on two axes,
and has no limits,
then we get a free hinge
that can rotate
only around single axis.
If we added minimum
and maximum angular limits,
then we'll get a limited hinge.
And in this way, custom Joints
can be constructed.
We've also overhauled
the Hit collectors.
Previously,
for performance reasons,
you had to transform
the Hit information
based on whereabouts
a particular shape
was hit, in the body hierarchy.
This was difficult and we've
handled all of this work now

English: 
so you only need to implement
the AddHit() function.
For example, this demo
shows a Raycast
going through a world
and checking the Hits.
If a particular Physics shape
is transparent,
if it has a particular flag
set, then we
return false, we don't
add that Hit.
And if it is opaque, then we
collect all of that Hit Information
and return it to the user.
We've also consolidated
a number of flags,
whether a particular Physics Shape
should be a Trigger,
a volume that can
be entered and exited
by other Rigidbody shapes
or whether a particular
Physics Shape should raise
Collision Events
and we've consolidated these into
a single Collision Response enum.
Now you can have
a Physics Shape that will collide,
it'll bounce around and effect
the Collision Response.
It could collide and also raise
Collision Events.
It could raise Trigger Events,
i.e. it's Trigger volume.
But there's this new
option of None.

Chinese: 
你只需要实现 AddHit() 函数
例如，这个演示展示了一个射线投射
穿越世界并检查命中数
如果一个特定的物理形状是透明的
如果设置了一个特定的标志
那么我们返回 false，不添加命中
如果它是不透明的，那么我们收集所有的
命中信息并返回给用户
我们还合并了一些标志
一个特定的物理形状是否应该是一个触发器
一个体积是否可由其他刚体形状进出
或者一个特定的物理形状
是否应该引发 Collision 事件，我们已经
将这些合并到一个 Collision Response 枚举中
现在你可以有一个可碰撞的物理形状
它会反弹并影响 Collision Response
它可能会碰撞并引发 Collision 事件
它可能引发 Trigger 事件，即它的触发器体积
但是有一个新的选项 None

English: 
A Physics Shape could be on
a compound body, for example,
not have any effect, in terms
of the Collision Response
but it will be there
for Raycasting.
There also is the option
in the future
to have Raise Collision
Event only option
whereby it's
a Physics Body, it collides
with the world and collects
that collision information,
but it doesn't
actually respond to it.
And this could allow users
to implement their own
collision response.
The Trigger and Collision events
samples have also been overhauled.
We've added a new system to parse
the Trigger streams
and the Collision streams,
and convert this information
and assign it to dynamic buffers
on the tagged Entities
that you're interested in.
This allows us to add Enter,
and Stay and Exit states,
and also allows us to handle
multiple Trigger overlaps.

Chinese: 
一个物理形状可能是一个复合体。例如
在 Collision Response 方面没有任何影响
但是影响射线投射
未来还有一个选项
只引发 Collision 事件
也就是说，它是一个Physics Body
它与世界碰撞，并收集碰撞信息
但它实际上并不响应
这可以让用户实现
自己的碰撞响应
Trigger 和 Collision 事件样本
也已经过彻底改造了
我们添加了一个新的系统
来解析 Trigger 流和 Collision 流
并转换这些信息，将其分配给
你感兴趣的标记实体的动态缓冲区。
这允许我们添加 Enter、Stay 和 Exit 状态
也允许我们处理多个触发器重叠

Chinese: 
所以在有两个力场的特殊情况下
处于两个力场中的物体
将会有两倍的作用力
在这个更改材质演示中，你可以看到材质
在进入时发生了变化，在退出时又发生了变化
现在有一个警告。
这确实引入了状态
如果你使用 Unity Physics 是想获得便利
能简单指定物体
先前的位置和方向，并且你也想使用
你需要考虑如何保存状态信息
以便在回滚时具有确定性
为此，这些系统目前在样本集中提供
根据社区对所需功能的响应
我们会将它推进到完整的模拟包中
我相信每个人都感兴趣的是
无状态物理模拟中的堆叠

English: 
So in that particular case
where there's two force fields,
a body inside both will have
twice the amount
of the force applied.
And in this Change Material demo,
you can see that the materials
changed on Enter
and changed again on Exit.
Now there's a caveat.
This does introduce state.
So if you're using Unity Physics
in order to get the benefits
of being able to simply assign
the previous positions
and orientations of the bodies,
and you also want to use this,
you need to consider how you save
that State information
in order to get determinism
if you want to roll back.
To that end, these systems
are currently in the sample set
and as the community responds
to what they wish,
we can push this
into the full simulation package.
I'm sure everyone's interested
in this one too. This is stacking
in a stateless Physics simulation.

English: 
Now, this is being
discussed in the forums.
It is possible to do this now
with a motion clipping-style system
using the
PostSolveJacobians callback.
This particular SimulationCallback
happens just before
the body positions are integrated
but after the Collision Responses
have changed the velocities
on the bodies.
So, if you check
the velocities at this point
and see if they're below
a particular threshold,
you can set them 0,
then this gives us stacking.
The question is what is
this heuristic that you're using
in order to clip
these velocities to 0?
There are cons
to this setup as well.
You can get strange orientations,
such as the cylinder
that gets stuck because
the velocities
aren't big enough.
The friction model
is also not fully accurate
in that if you pull a box
from the bottom of a stack,
and there's a strong
or high friction
between the body on the bottom
and the body on the top,

Chinese: 
现在，论坛上正在讨论这个
现在可以使用运动裁剪风格的系统
使用 PostSolveJacobians 来实现这一点
这个特殊的 SimulationCallback
发生在物体位置被整合之前
但是在 Collision Responses
改变物体上的速度之后
所以，如果你检查这个点的速度
看看它们是否低于一个特定的阈值
你可以把它们设置为 0，然后就可以获得堆叠
问题是，你用什么样的启发式方法
来把这些速度裁剪到 0？
这种设置也有缺点
你会得到奇怪的方向
比如圆柱体因为速度
不够大而被卡住
摩擦模型也不完全准确
因为如果你从堆叠的底部拉出一个盒子
并且在底部的物体和顶部的物体之间
有很强或很高的摩擦力

Chinese: 
那么就不能很好地应用摩擦力
所以你可以很容易地把盒子
从堆叠的底部滑出
现在，如果你有一个更复杂的设置
可能会得到一个更好的结果
但是我们已经直接在这个模拟后端添加了一个
这个实现要好多了。它看起来对速度进行了裁剪
并且依据摩擦模型本身
以及摩擦模型应用的速度
它在模拟本身
和模拟的子步骤中实现
还可以查看涉及的物体数量
例如，一堆箱子中间的一个箱子
会受到周围箱子的影响
顶部、左侧、右侧和底部
根据场景中涉及的物体数量
还可以对一些碰撞响应做出调整
尽管仍然有些缺点

English: 
then that won't get applied
appropriately,
so you'd be able to very easily
slide the block
from the bottom of the stack out.
Now, if you have a more
complicated setup,
you could probably get
a better result.
But we've added one straight
into this simulation backend.
This does a lot more. It looks.
of course, clipping the velocities,
but it also looks at
the friction model itself
and the velocities being applied
by that friction model.
So it's doing work
in the simulation itself
and in the substeps
of the simulation.
It can also look at the number
of bodies involved,
so a box for example,
in the middle of a stack of boxes
is being affected
by boxes all around;
the top, left, right and bottom.
And based on the number
of bodies involved in a scenario,
we can also scale some
of the Collision responses.
There are still cons with this
but you'll have to drag

Chinese: 
不过你必须把你的盒子拖下来
堆叠物体才会坍塌
之前，摩擦误差会随着时间的积累
从而导致不稳定的情况
当然，对于本来就不稳定的场景
仍将发生坍塌
我们来看看最新版本的 Havok Physics for Unity
模拟后端的一些特色功能
Havok Physics 软件包是
基于 Havok Physics SDK 2019.2 版本构建的
当然，我们将很快发布新的 2020.1 版本的
Havok Physics SDK
Unity 软件包也将相应更新
我们目前确实支持所有的新一代平台
但是如果你对其他平台有兴趣
请与你的开发者关系经理联系
Havok Physics 2019.2 版本

English: 
your box off, in order to cause
your stack to collapse
whereas previously, of course,
the friction errors
accumulated over time
leading to an unstable scenario.
Inherently, unstable scenarios,
of course, are still
going to collapse.
So looking at some of the feature
highlights in the latest version
of the Havok Physics
for Unity Simulation Backend.
The Havok Physics package
is built off
Havok Physics SDK version 2019.2.
We will be releasing
a new 2020.1 version
of the Havok Physics SDK
soon, of course.
The Unity packages
will be updated appropriately.
We do support all the 
current-generation platforms
at the moment, but please talk
to your Developer Relation Manager
if there's details on other platforms
you might be interested in.
One of the main features
that got added

Chinese: 
新增的一个主要功能
是支持更大的世界
这里，我们正在检查 Hello World 样本
我们进行模拟的范围
距离原点 10、100 甚至有点变态的 1000 公里
浮点误差从原点开始累积的更远
就物理模拟而言，这意味着抖动
即使在 100 公里以外
Unity Physics 模拟后端仍然相当不错
但是 Havok Physics 模拟后端正在更新
以支持这么远的距离
不管模拟后端如何
对于如鼠标选择的射线投射这类的查询
无论你使用的是 Havok 还是 Unity 模拟后端
查询都是一样的
所以，一旦到 1000 公里的距离
你都会在尝试捡起字母看到误差
将关节添加到场景中会加剧问题
因为碰撞响应和关节响应
都会累积误差

English: 
into the 2019.2 version
of Havok Physics
was support for larger worlds.
Here, we're checking
the Hello World sample
and we're simulating at 10, 100,
and, for a bit of a laugh,
1000 kilometers from the origin.
Floating point errors accumulate
the further from the origin
and in terms of Physics simulation,
this means jitter.
Unity Physics Simulation Backend
is still pretty good
even out to 100 kilometers.
But Havok Physics Simulation Backend
is being updated specifically
to support these sort of distances.
Regardless of the Simulation
Backend,
it's worth highlighting
that the queries, such as
the Raycast used for
mouse-picking, are the same,
whether you're using the Havok
or Unity Simulation Backend.
And so, whenever we get
to 1000 kilometers,
you can see the error
in trying to pickup the letters.
Adding joints into a scenario
exacerbates the problem
as the errors accumulate
both on the Collision response
and the Joint response.

Chinese: 
所以即使是 Havok
我们在 100 公里处的布娃娃也在抖动
有时很难知道这种抖动的原因是
图形的还是物理的
Unity 模拟后端中提供了停用功能
对于 100 公里处，可帮助我们消除
这一现象
不过，在 2000 公里的位置出现布娃娃
可能不是个好主意
随着 Havok Physics 2020.1 的发布
我们还将引入 Holonomic 关节
Direct Solver（直接解算器）选项
当我们在约束链的末端处理非常重的质量时
Havok 和 Unity Physics 中的
迭代求解器都可以引入柔度
直接解算器在这方面要严格得多
当然，你也可以混合使用迭代关节
和直接解算器组

English: 
So even with Havok, we're getting
jitter on our ragdolls
at 100 kilometers.
Though it's sometimes hard to know
whether some of that jitter
is graphics boiling
rather than physics.
Regardless, the deactivation
that's available inside
the Unity Simulation Backend
can also help even out
at 100 kilometers
with our ragdolls.
Probably not a good idea
to run ragdolls
at 2000 kilometer, though.
With the release
of Havok Physics 2020.1,
we'll also be introducing
a Direct Solver option
for Holonomic joints.
The iterative solver in both Havok
and Unity Physics
can introduce softness
whenever we're dealing
with very heavy masses
at the end of a Constraint chain.
The Direct Solver
is much stiffer in this regard.
And of course, you can mix
both iterative joints
and Direct Solver groups as well.

English: 
I wanna hand over
to Josh of Freejam.
Freejam have been building
Gamecraft for months now
and they've been using
Unity Physics.
And only relatively recently moved
to Havoc Physics, in order
to benefit from some of the
performance differences.
And I want them
to walk-through their story,
especially highlighting some of the
features of the Visual Debugger.
[JOSH] Hello, I'm Josh, and
I'm part of the Freejam Dev team.
We are the developers of Robocraft,
a hit free-to-play game
where users can create
their own robots to fight with.
We're now focusing
on developing Gamecraft
where users can create their own
games without typing any code
within minutes, and then share that
from the Steam Workshop
for others to play.
Gamecraft is
an open-Physics sandbox
where you can build anything
from a racing game,
to an adventure puzzler,
and everything in between.
Gamecraft can end up using
thousands of Rigidbodies
in complex physics-simulated joints,
based on the user's creation.
So it's important
that the Physics simulation
is not only fast,
it's accurate too.

Chinese: 
接下来，我们把时间交给 Freejam 的 Josh
Freejam 花了数月在构建 Gamecraft
他们一直在使用 Unity Physics
只是最近才迁移到 Havoc Physics
为了能提高性能
我想让他们介绍他们的故事
着重 Visual Debugger 的一些功能
[JOSH] 大家好，我是 Josh，Freejam 开发团队的一员
我们是 Robocraft 的开发者，一款热门的免费游戏
用户可以创建自己的机器人来对打
我们现在专注于开发 Gamecraft
用户可以在几分钟内不用输入任何代码
就能创建自己的游戏
然后从 Steam Workshop 分享给其他人玩
Gamecraft是一个开放的物理沙箱
在这里你可以建造任何东西，从一个赛车游戏
到一个探险迷宫等任何这类游戏
Gamecraft可根据用户的创作在复杂的
物理模拟关节中使用数以千计的刚体
因此，重要的是物理模拟不仅要快
而且要准确

English: 
For these reasons,
we decided to go fully ECS
and use the power
of Burst and Havok.
ECS and Burst allows us
to maximize the CPU throughput
while Havok exploits the same power
to perform complex simulation
with thousands of Rigidbodies
and dozens of thousands of Colliders.
In Robocraft, we had to deal
with several compromises
and write several
custom algorithms to optimize
the number of Entities
in the Scene.
With ECS, Burst and Havok,
we can go wild
and let the users experiment
with massive levels.
We don't even need to care
to perform any
optimization based
on the visibility yet
as the simulation runs
on all the Entities
at all times, everywhere
in the level, and still
provide exceptional results
in terms of performance.
Gamecraft is also
a multi-player game, but rarely
network games have seen this level
of physics simulation complexity.
SInce our network approach is
not based on a deterministic model,
choosing Havok over Unity
Physics ECS has been a no-brainer.
In our case, every nanosecond
available is a nanosecond
that can used to make
the game more sophisticated.

Chinese: 
出于这些原因，我们决定拥抱 ECS
借助 Burst 和 Havok 的威力
ECS 和 Burst 允许我们最大化 CPU 吞吐量
而 Havok 则利用同样的能力，
对数千个刚体和数十万个碰撞体进行复杂的模拟。
在 Robocraft, 中，我们必须进行一些妥协
并编写一些自定义算法来
优化场景中实体的数量
有了 ECS 、 Burst 和 Havok，我们可以尽情发挥
大幅提升用户体验
我们甚至不需要关心
执行任何基于可见性的优化
因为模拟始终在所有实体上运行
在关卡的任何地方
并且仍提供卓越的性能
Gamecraft 也是一款多人游戏
但是很少有网络游戏有如此复杂的物理模拟
由于我们的网络方法不是基于确定性模型
顺理成章会选择 Havok 而不是 Unity Physics ECS
在我们的例子中，每一纳秒
都可用来使游戏更加完善

Chinese: 
因此，Havok 基于缓存的实现在性能和额外稳定性
方面的提升这是我们所追求的
Havok 不仅在性能上帮助我们
集成的 Visual Debugger 将调试速度提高了 10 倍
♪ [MUSIC PLAYS TO END] ♪
让我们从这个简单的场景开始
我们已经布置好了这些立方体
所以当我们进入模拟时，它们会掉进洞里
然而，当我们进入模拟时，可以注意到
立方体没有正确地落入它们的孔中
因此，如果我们打开 Visual Debugger
可以发现斜面半径没有被正确应用
如果我们快速修复
并进入 Visual Debugger
在进入模拟时我们可以看到斜角半径现在被应用
立方体正确地落入各自的孔中

English: 
Hence, Havok cache-based
implementation
gives that nice boost in performance
and extra stability that we are after.
Havok didn't only help us
performance-wise.
The integrated Visual Debugger
sped up our investigations tenfold.
♪ [MUSIC PLAYS TO END] ♪
Let's start with this simple Scene.
We've laid out these cubes
so they will fall into the holes
when we enter simulation.
However, when we enter simulation,
we can notice the cubes
do not correctly fall
into their holes.
So, if we open the Visual Debugger,
we can find out
that the bevel radius
is not being applied correctly.
So if we quickly fix this
and have another look at
the Visual Debugger, we can see the
bevel radius is now being applied,
which allows for the cubes
to correctly fall
into their holes
when entering simulation.

Chinese: 
在另一种场景里，我们遇到了一个问题
关节受到一些奇怪的力
因此，我们使用 Visual Debugger 返回时间轴
查看可能导致问题的原因
经过调查，我们发现
关节本身存在接触点
我们决定过滤掉这些接触点
以防止施加奇怪的力
这里你可以看到工作正常
这些接触点在 Visual Debugger 中显示为灰色
Visual Debugger 还可以处理大型复杂的关卡

English: 
In another situation,
we had an issue
where Joints were receiving
some strange forces.
So we used the Visual Debugger
to go back in the timeline
to see what may
be causing the issue.
Upon investigation, we found that
there were contacts being made
in the joints themselves.
We decided to filter out
these contacts
to prevent the strange forces
being applied
which you can see
working correctly here
as those contacts are now appearing
as gray in the Visual Debugger.
The Visual Debugger can also handle
large and complex levels.

English: 
I'll show you a quick time-lapse
of this level that contains many joints,
moving Rigidbodies,
and a lot of collisions.
[STEVE] I now want to look at
some of the common use cases
linked to a Physics simulation
and how we can utilize
all of the information and features
you've seen so far, to get
the behavior behind a vehicle
or a ragdoll,
or a Character Controller,
to be exactly what we want.

Chinese: 
我将向你展示这个关卡的快进，它包含许多关节
移动刚体和许多碰撞
[STEVE] 我来展示一些与
物理模拟相关的常见用例
以及我们如何利用到目前为止
你所看到的所有信息和功能
让车辆、布娃娃或角色控制器背后的行为
完全符合我们的需求

English: 
So looking at vehicles, of course
we can have detailed vehicles
like the tank we saw
in the Freejam example
or the digger we can see here.
But we can also have
a very simple representation
of a vehicle, simply pushing
a Body around the Scene.
We can utilize the Custom Joints
that we talked about
to build up elaborate
Wishbone systems,
or we can manipulate Contacts
as they flow through the simulation
to introduce a sort of softness,
whether it's for tires,
or whether it's to remove
the rigidity of a collision
with a vehicle and a wall.
And the Collision Events
have been updated
so that you can get information
like whether it's a vertex
or an edge or a face
that's been hit.
And higher level proximation
information as well as of course,
digging fully into the full
contact manifold.
These screenshots are
from the Tiny Racing sample
and they literally are just
pushing boxes around the world.
But I want to highlight
two physics properties:
the Bevel Radius
and the center of mass.

Chinese: 
这些车辆，当然我们可以有细节丰富的车辆
比如我们在 Freejam 例子中看到的坦克
或者我们在这里看到的装载机
我们也可以用一个非常简单的车辆表示
只是在场景中推动一个物体
我们可以利用前面讨论过的自定义关节
来构建复杂的 Wishbone 系统
或者我们可以在模拟过程中操纵接触点
从而引入一种柔度，不仅针对轮胎
还可以消除与车辆和
墙壁碰撞的刚性
碰撞事件已经更新
这样你就可以得到具体信息
被击中的是一个顶点、一条边，或是一个面
还有更高层次的接近信息
当然，充分挖掘整个接触复合体
这些截屏来自 Tiny Racing 样本
它们实际上只是在世界中推进的盒子
但是我想着重介绍两个物理属性
斜角半径和质心

English: 
Whenever you're colliding
bodies together,
there are two different
algorithms used,
depending on whether
the bodies are separated
or whether
they're interpenetrating.
The interpenetrating algorithm
can be much more expensive.
So we introduced a Bevel Radius;
we shrink our body down slightly,
and give it an extra convex radius
which acts as a numerical buffer.
It also introduces
roundness at the edges,
so a box becomes beveled,
for want of a better word.
You can imagine
if two boxes didn't have
this Bevel Radius; one sitting
on top of the other.
Then the top face of one box,
and the bottom face of the other
would be perfectly aligned
from frame to frame.
They can be bouncing from a
non-penetrative to a penetrative state.
So, the Bevel Radius
is a good numerical tolerance
to keep away from that more
expensive interpenetrating algorithm.
We'll get some videos up online
to highlight the differences
between those algorithms in future.

Chinese: 
每当你碰撞物体时
会使用两种不同的算法
这取决于物体是分开的
还是相互穿插的
穿插算法的成本可能要高得多
所以我们引入了斜角半径，可以稍微收缩物体
给它一个额外的凸半径
作为数字缓冲
它还在边缘引入了圆形
所以盒子带有斜角，可能有更好的术语
你可以想象如果两个盒子没有这个
斜角半径，上下摞起来
这样，一个盒子的顶面和另一个盒子的底面
将会完全对齐
它们变从非穿透状态反弹到穿透状态
因此，斜角半径是一个很好的数值公差
避免了成本高昂的穿插算法
我们将在网上发布一些视频
来强调这些算法之间的差异

English: 
So this Bevel Radius let's us push
a box around the world
and adds smoothness
as the box is being pushed
along the ground,
and it's adding a curved edge,
so as it grinds along the wall
it doesn't get a hard knock
from the very corner of a box.
The center of mass of a body
automatically tries to go to
the geometric center, which
in this particular case would be
around where the driver
of this cart would be.
But because we're simulating
the cart with a box,
if we tip our cart on the side,
it'll stay there.
Now, the smooth roundness
from the Bevel Radius
does help whenever
it's not fully tipped
on its side to roll back
onto its base.
But by lowering the center of mass,
that's this purple box you see there,
the mass property
is being highlighted;
if we lower that
below the cart itself,
then we will introduce
a weeble-style effect.
So, with the low center of mass,
you can see that it does help
these vehicles
after a major collision,

Chinese: 
这个斜面半径使得盒子可以四处推进
沿着地面推进时
提升了平滑度，当它沿着墙壁时
增加了一个弯曲边，避免盒子的角
受到猛烈的撞击
一个物体的质心自动与达几何中心重合
在这个特定示例中
几何中心位于车辆驾驶员附近
但是因为我们用一个盒子来模拟车辆
如果我们把车辆一边着地，它会保持侧立
现在，斜面半径的平滑圆度
确实有助于车辆尚未完全侧立时
回到直立状态
通过降低质心，这就是这个紫色的盒子
质量属性被突出显示
如果我们把质心降低到车辆下面
那么我们将会引入一个摇摆的效果
所以，在低质心的情况下，你可以看到它确实
有助于这些车辆在激烈碰撞后

English: 
to go from hanging on its side
to going upright again.
Of course, if there's a major
collision, you might want to reset
the center of mass
to be more appropriate
so that the car doesn't spin
through the air in a strange manner.
Whenever we're considering
the data collection for vehicles,
it's worth looking
at the Cast Collider.
You can cast any shape you like.
So if you've got a tire,
you could instead
of using a Raycast, as we do
in a very simple vehicle samples,
you could cast an actual cylinder,
representing the wheel.
So, whenever your car is going over
a steep transition in the terrain,
the wheel itself will get
an appropriate hit
rather than just from a ray point.
It could hit on the
tire's edge or the back,
giving much more information.
Whenever you're filtering
collision, and indeed, queries,
it's worth highlighting this
extra feature in the CollisionFilter
of the GroupIndex.
It's not exposed in the UI yet,

Chinese: 
从侧翻状态恢复到直立状态
当然，如果发生了大碰撞
你可能需要将质心重新设置到合适的位置
这样汽车就不会以奇怪的方式在空中旋转
每当我们考虑为车辆收集数据时
有必要查看一下投射碰撞体
你可以投射任何你喜欢的形状
对于轮胎，你可以不使用射线投射
就像非常简单的车辆样本中所做的
你可以投射一个圆柱体，代表车轮
每次车辆经过地形中一个陡峭的过渡时
车轮本身会得到适当的撞击
而不仅仅是来自一个放射点
它可以击中轮胎的边缘或背面
提供更多的信息
每次在过滤碰撞，也就是查询时
值得关注 GroupIndex 的 CollisionFilter 中
提供的额外功能
该功能尚未在 UI 中公开

English: 
but if all the elements
of a vehicle
are given a particular
vehicle number, for example,
and they all set
their CollisionFilter.GroupIndex
to be a negative value,
the same negative value,
then they won't collide
with each other, which is great
whenever you're trying to do
a query for your wheels
without having to hit the actual
chassis of the vehicle itself.
It's also worth considering
the Update Order.
Are you working,
for example, with the
ECS ComponentData information?
Or are you working with
the Simulation Random Access data?
If you're working
with the Entity ComponentData,
it's worth highlighting
that if your system is updating
between Step Physics World
and Export Physics World,
then the Export Physics World
system will actually
overwrite your information.
If you're performing
queries on the world,
it's worth highlighting that
if you perform those queries
before the Build
Physics World is stepped,
you will be dealing with information
from the previous frame.

Chinese: 
例如，如果车辆的所有元素
都有一个特定的车辆编号
它们都将 CollisionFilter.GroupIndex
设置为一个相同的负值
这样它们就不会相互碰撞，这在你试图查询
车轮而不碰到车辆本身的
实际底盘时非常有用
Update Order（更新顺序）也值得了解
例如，你是否正在使用
ECS ComponentData？
或者你在使用 Simulation Random Access 数据？
如果你使用的是实体 ComponentData
值得强调的是，如果系统在 Step Physics World 和
Export Physics World 之间更新
那么 Export Physics World 系统
实际上会覆盖你的信息
如果你在世界中执行查询
值得强调的是，如果你步进 Build Physics World
之前执行这些查询
你将处理来自前一帧的信息

English: 
Now there is a flag that you
can set in Physics Step, now
to synchronize the Collision World
at the end of the Step
Physics World.
That means that
if you're running vehicle systems
after Step Physics,
and Export Physics,
then you will be getting
query information for that frame.
Now you're duplicating
a slight bit of work
that's in Build Physics World
but that option is there.
It's also worth considering how
you're chaining your systems together
Build Step and Physics World
are separate systems
so if you're wanting to slot
your own system between them,
then we've implemented a new
IPhysicsSystem interface
with an AddInputDependency
and a GetOutputDependency,
and these JobHandles
can then be used
to chain your jobs appropriately
in your own system OnUpdates.
I want to just consider
tracked vehicles, as well.
This particular demo
is manipulating
the contact information to
introduce a fake surface velocity.

Chinese: 
现在有一个可在 Physics Step 设置的标志
实现在 Step Physics World 末尾
同步 Collision World
这意味着，如果在 Step Physics 和
Export Physics 之后运行车辆系统
那么你将获得该帧的查询信息
现在，你正在重复 Build Physics World 中
的一点工作，但已经提供了该选项
同样值得考虑的是，如何将系统链接在一起
Build Step 和 Physics World 是独立的系统
如果你想在它们之间插入你自己的系统
我们实现了一个新的 IPhysicsSystem 接口
带有一个 AddInputDependency
和一个 GetOutputDependency
这些 JobHandle 可用于将你的作业
链接到自己的系统 OnUpdate 中
我还要提一下履带式车辆
这个特别的演示是操纵接触信息
来引入一个虚拟的表面速度

English: 
This is great for something
like a conveyor belt,
where the movement can just be
say, a UV scroll
on the graphical element
and you don't actually need
moving parts.
This demo shows a tank.
Each wheel is just
simulated by a box
that's held to the chassis
with a prismatic joint.
There is no rotation.
The rotation is purely
a graphical effect.
And the motion is simply
from the boxes
representing each wheel
having a fake
surface velocity with the terrain.
Of course, whenever this demo
is fully released,
we need to add the tank tracks
in for full effect.
I now wanna touch on ragdolls.
There's a lot we can talk
about with ragdolls
and broadly split up into
how do we set our ragdoll up
and then how do we control it.
And there's enough
information there
for a full talk
in and of in itself
but I only wanna look two things:
the ragdoll joint that's available
and the notion of passive dying,
a passive ragdoll,

Chinese: 
这对于像传送带这样的东西来说非常适用
这里的运动可以说是
图形元素上的一个 UV 卷轴
你实际上不需要移动部件
这个演示展示了一个坦克
每个轮子都是由一个盒体模拟的
盒体通过一个棱形关节固定在底盘上
没有旋转
旋转纯粹是一种图形效果
这个运动是简单的从代表每个轮子
的盒体里得到的，每个轮子
都有一个相对地形的虚拟表面速度
当然，等到这个演示完全发布时
我们需要添加坦克履带来获得完整的效果
我现在想说说布娃娃
我们可以就布娃娃讨论很多内容
大致可以分为如何设置布娃娃
如何控制布娃娃
这里有足够的信息来进行完整的讨论
但我只想涉及看个方面
一个是有哪些布娃娃关节
另一个是被动的概念。被动型布娃娃

English: 
just a set of bodies and joints,
flowing through the world.
In particular, I wanna highlight
the Ragdoll Joint.
We saw how to build our own
Custom Joints
out of the Constraint atoms,
and indeed the Ragdoll Joint
is actually two joints,
two child joints.
One of those joints
has a 1D Angular Constraint
that represents
a twist along an axis,
and the other
is a 2D Angular Constraint
that provides angular motion
within a cone shape.
And then there's a second joint
that has another 2D Angular Joint,
which represents
an extra space limit.
And a 3D Linear Joint, which
is basically a ball and socket.
When we put those together,
we can end up creating
a very elaborate shape,
very appropriate
for something like a hip joint
on a character or shoulder joint.
To highlight this
in a little bit more detail,
let's show how to setup
a Ragdoll Joint
on a hip of a character.

Chinese: 
只是一组身体和关节，在世界中流动
我想特别强调一下布娃娃关节
我们看到了如何从约束原子构建我们
自己的自定义关节，事实上，布娃娃关节
是两个关节，两个子关节
其中一个关节有一个 1D 角约束
表示沿轴的扭转
另一个关节有一个 2D 角约束
提供了圆锥形状内部的角运动
第二个关节有另一个 2D 角关节
这代表了额外的空间限制
和 3D 线性关节，基本上是一个球窝关节
当我们把它们放在一起时
最终可以得到一个非常精致的形状
非常适合像人物的髋关节
或肩关节这样的结构
为了更详细地强调这一点
我们展示一下如何在角色的臀部
设置一个布娃娃关节

English: 
This example Scene shows
part of a leg, a pelvis,
a thigh and a shin.
And I just wanna show some of the
constraints that are setup for this.
Here we wanna put a limited hinge.
We want our knee to be able
to move backwards but not forwards.
So whenever we're dealing
with a limited hinge,
we want to setup
an axis to rotate
around, that's this
white arrow here,
represents both
the position of the hinge
and the axis it wants
to rotate around.
And also there are limits. This here
is currently representing our limits
which are set up
at zeroes at the moment.
Now, the limits I want to set
for this particular case,
probably about minus 100,
and that means that the child body
is going to be able to move
around our hinge axis
within that range.
So if I play this now,
we've got our knee
swinging in a particular direction.

Chinese: 
这个示例场景显示了腿的一部分、骨盆
大腿和胫骨
我只想展示一些为此设置的约束
这里我们放一个受限铰链
我们希望膝盖能够向后运动，而不是向前
所以当我们处理一个受限铰链时
都要设置一个旋转轴
这里白色的箭头代表
铰链的位置和
它要围绕其旋转的轴
而且还有极限位置。这个目前代表了极限位置
当前被设置为零
现在，为这个特定的例子设定的极限位置
大概是负 100
意味着子对象将能够在这个范围内
绕着我们的铰链轴运动
如果我现在播放
膝盖会向一个特定的方向摆动

English: 
Now, we need to look at the Ragdoll
Joint and see what's going on there.
This is a much more
complicated joint at this hip.
It needs to be able to move
in all directions, but be constrained,
and we use a Ragdoll Joint
to illustrate this.
There are two components
as we said.
There's the general axis of
movement that's represented here
by these two white arrows,
and the reason they're different
is because we've now separated out
the constraints bases.
This arrow represents
the constraints base in the thigh
and this represents
the constraints base in the pelvis.
And this is telling us
how much movement in general
can this particular joint have.
So, if I increase
the cone angle here, for example,
we're basically saying that my leg,
my thigh, this arrow,
needs to stay within in this space
being defined by the cone angle

Chinese: 
现在，我们看看布娃娃关节，看看发生了什么
这是一个髋关节，要复杂的多
它需要能够在所有方向上运动，但受到约束
我们用一个布娃娃关节来说明这一点
正如我们所说，有两个组成部分
这是运动的总轴，这里用这两个白色箭头表示
做出区分的原因是
我们现在已经将约束基础分离
此箭头表示大腿中的约束基础
这表示骨盆中的约束基础
这告诉我们这个特殊的关节
一般能具有多少运动
举例来说，如果我增加锥角
我们基本上是说，大腿，这个箭头
需要保持在由锥角和骨盆空间的箭头

Chinese: 
定义的空间内
例如，可能 60 度比较合适
这样的话，腿可以向前摆动
也可能把膝盖抬向胸部
但不能向后摆动
如果这个代表骨盆空间的箭头
指向正下方，可以在两个方向上
均匀地摆动腿。现在，腿向前运动的幅度
远大于向后运动
这里，腿不能向前，但可以把膝盖抬高
腿不应该完全自由地
在这两个方向上运动，我们想限制它
这样它就不能在一个方向上幅度太大
在另一个方向上也幅度太大
所以，我们也可以对布娃娃关节
考虑垂直轴
这是沿着 X 轴设置的

English: 
and the arrow in the pelvis space.
So this might be a good
say 60 degrees, for example.
That way then,
the leg can swing forward
and maybe bring its knee
up towards its chest
but it can't swing backwards.
If this arrow, representing
the space in the pelvis
was pointing straight down,
then we could swing our leg evenly
in both directions, but now
we can move our leg
forward much more
than we can move it backwards.
Here, I can't drag my leg forward,
but I can lift the knee up.
Now, a leg shouldn't be able
to move fully freely,
in both of these directions,
and we wanna limit it
so it can't go much further
than that in one direction
and much further than that
in the other.
So, we can also,
on the Ragdoll Joint,
consider the perpendicular axis.
This has been set up
to be along the X-axis.

English: 
This white arrow,
might be a little bit hard to see,
but there's a white arrow
that's coming out
from the side of the pelvis.
This allows us to put extra limits
on this space
rather than being fully free
to move within that entire cone.
We can now reduce the limits
so that the leg can't
go fully doing the splits,
maybe this is good
at 30 degrees, for example.
And we definitely
don't want the leg
to be able to swing freely
that way.
We'll maybe bring this down
so that it's much more constrained.
No, not in the right direction,
I've overlapped the wrong way.
So here we wanna pull it down
to say 100 degrees.
And it's 100 degrees
from this white arrow.
Now the limb will only be allowed
to move within this area,

Chinese: 
这个白色的箭头，可能有点看不清
但是有一个白色的箭头
从骨盆的侧面伸出
这让我们可以对这个空间施加额外的限制
而不是完全自由地在整个圆锥体中运动
我们现在降低极限值
这样腿就不会摆成一字马了
例如，可能 30 度比较合适
我们绝对不希望腿
能那样自由摆动
我们也许会把它降下来，这样它就更受约束了
不，方向不对，覆盖错了
所以我们想把它降下来，比如 100 度
它和这个白色箭头成 100 度
现在肢体只能在这个区域内活动

Chinese: 
这个体积，是由这个黄色和红色的圆锥体定义的
沿着关节本身的轴线还有一个元素
我们也可以让腿稍微扭曲一下
我们就可以在这里增加一点扭曲动作
你会看到，然后在脚本身
将被允许扭曲
现在，我的腿可以向前运动，但不能向后运动
当我从侧面看时，它只能向内运动一点点
但可以向外运动很多
这样，我们可以从布娃娃关节获得
一个臀部和肩部这类非常复杂的空间
因此，该设置非常自然地显示了关节极限
至少对于一个 Physics 开发者来说是这样
你在屏幕上看到的演示是一个完整的
布娃娃设置，相当自然，活动范围也受限
现在，有了这些限制

English: 
this volume, that's defined
by both this yellow and red cones.
There's one further element
along the axis of the joint itself.
We can also let
the leg twist a little bit
so we can add just a little bit
of a twist motion on here.
You'll see that then
in the foot itself,
will be allowed to twist.
Now, my leg can move forward
but it can't move back,
and when I look at it from the side,
it can only move in a little bit
but it can move out quite a lot.
So we can get a very complex space
for the likes of a hip
and a shoulder
from the Ragdoll Joint.
So that setup showed the Joint
limits at fairly natural extent,
at least for the hip
of a Physics programmer.
The demo you're seeing
on screen at the moment
is a full ragdoll setup with fairly
natural, limited extents as well.
Now, with those limits,

English: 
the ragdoll can look too floppy
if you just throw it
into the world.
These are considered
passive ragdolls.
We're not doing anything
other than simulating
the Collision response
on the Joint.
But they have natural limits
which sometimes can look good
and sometimes look just too floppy.
An active ragdoll
is motorizing the joint
between an arm or a torso,
or keyframing a body
if you're wanting to have hands
specifically holding on to something
or moving in a particular
way with IK.
There is a cheap way
of doing an active ragdoll
without having all of that
animation blending setup.
Which is coming!
I'll show us a little
brief example of that
in the coming months.
But a cheap way of implementing
an active-type ragdoll
is just simply to halve the limits.
When the limits are violated,
of course, the iterative solver
tries to bring that constraint
back within those halved limits,

Chinese: 
如果你把它扔进世界
它可能看起来太松弛了
这些被认为是被动型布娃娃
除了模拟关节上的碰撞响应
我们没有进行其他设置
但是它们有天然的限制，有时效果很好
有时看起来太松弛了
一个主动型布娃娃可以机动化手臂或躯干
之间的关节，或者如果想让手专门抓住某物
或者使用 IK 以特定的方式移动
可以给身体设定关键帧
有一种简便的方法制作主动型布娃娃
而不需要设置全部动画混合
就要看到了！在接下来的几个月里
我将向我们展示一个简单的例子
但是实现一个主动型布娃娃的一个简便方法
就是将限制减半
当然，当限制被违反时，迭代解算器会试图
将约束带回到那些减半的限制内

Chinese: 
这看起来有点像肌肉型的效果
这是同样的演示，但是限制减半
手臂被拉向人的头部
当他们从楼梯上摔下时，会有更多的滚动特效
膝盖也会向胸部抬高
这当然有些主观，但这是一种非常简便的
获得主动型响应的方法
说到这，DOTS 动画团队正致力于
与 Unity Physics 的完全集成
添加主动型布娃娃的用例
该选项能够根据动画设置布娃娃
让动画驱动物理
并且物理驱动动画
可以在接下来的几个版本中关注
对于角色控制器用例的讨论
我想交给 Philippe
他在这个领域做了大量的工作
[ PHILIPPE ] 大家好，我是 Philippe St-Amand
我将谈谈我在 DOTS 中

English: 
and it looks like a little bit
of a soft muscular type effect.
So, here's the same demo
but with the limits halved.
The arms get pulled up
towards the person's head.
There's much more of a rolling effect
as they fall down the stairs,
and the knees are kind of brought
up towards their chest as well.
Some of this subjective of course,
but it's a very cheap, simple way
of getting an
active-style response.
Having said that,
the DOTS animation team
are working on full integration
with Unity Physics
to add in the Active
Ragdoll use case,
this option of being able to setup
your ragdoll based on your animation,
have the animation
drive the Physics,
and the Physics
drive the animation.
So look out for that
in the next couple of releases.
To discuss our Character
Controller use case,
I want to hand over to Philippe.
who's been working
extensively in this area.
[PHILIPPE] Hello, my name is
Philippe St-Amand
and I'll be speaking for a bit
about my experience

Chinese: 
制作角色控制器的经验
过去，我使用过一个资源
叫做运动角色控制器
它是一个 MonoBehavior 角色控制器
我基本上想做一个完全相同的东西，但用于 DOTS
这意味着使用一个全新的架构，甚至是
新的物理引擎，也就是 Unity Physics 和 Havok
但最终，我的目标是为 DOTS 创造一个直观的
优化的、易于使用的
高度可扩展的角色控制器
它应该能够很好地适合这两个用例
首先，我们定义一下什么是角色控制器
这是非常主观的，没有明确的答案
但是就这个项目而言
角色控制器是一个物理形状或碰撞体
它移动并与环境碰撞
检测地面并保持接触
比方说，如果你被地板上的凸起
绊了一下，你不一定希望

English: 
with making a Character
Controller in DOTS.
So in the past, I've worked
on an Asset
called Kinematic Character Controller
which was a MonoBehavior
Character Controller.
I basically wanted to make an exact
equivalent of it but for DOTS
and that means working with
a completely new architecture
and even new physics engines,
which are Unity Physics and Havok.
But at the end of the day, my goal
was to create an intuitive
and optimized, easy-to-use,
and very extensible
Character Controller for DOTS.
It should be able to be
a good fit for both use cases.
Let's just take a moment to define
what we mean by Character Controller.
It's very subjective and there's
no definitive answer to it
but in the context of this project,
a Character Controller
is a physics shape or collider,
that moves and collides
with the environment,
that detects the ground
and sticks to it.
Let's say if you're running over
a little bump on the floor,
you don't necessarily
want your character

English: 
to go flying up into the air.
You'll probably want it
to snap to the ground's surface
and adjust its velocity
to the ground's slope.
And Character Controllers can do
extra things
like standing on moving platforms,
or pushing dynamic Rigidbodies.
Now you could probably achieve
most of these things
with a dynamic Rigidbody character,
and that would be perfectly fine
for a lot of use cases,
but often with dynamic characters,
you'll end up running
into some little problems
or little edge cases
that would be solved
way more easily
with a Kinematic character.
And a Kinematic character
is something that uses
only Physics queries to collide
with the environment
instead of Rigidbody Physics.
Some examples
of the kinds of problems
you might run into
with dynamic characters
are things like making sure
you don't bump into the air
when you move against
a really steep slope,
or making sure there's
no velocity loss
or deviation when you
move on rough terrain.

Chinese: 
你的角色飞到天上
你会希望它贴紧地面
并根据地面坡度调整它的速度
角色控制器可以做额外的事情
比如站在移动的平台上，或者推动动态刚体
现在你可以用一个动态刚体角色
实现大部分目标
这对于很多用例来说非常适用
但是动态角色经常会遇到一些
小问题或者小的边缘情况
此时，用运动角色会
更容易解决
运动角色仅使用 Physics 查询
与环境碰撞
而不是 Rigidbody Physics
动态角色可能会遇到的
一些问题的例子是
当你在一个非常陡峭的斜坡上移动时
要确保你不会撞到空中
或者当你在崎岖的地形上移动时
要确保没有速度损失或偏差

English: 
Or finally, making sure that
you have very precise,
continuous collision detection at high
speeds, so you don't go through things.
So for these reasons,
this character I'm making
is a Kinematic character.
Now, let's talk about using
Unity Physics and Havok
in the context of this project.
These are your two options
for Physics and DOTS
and since they share the same APIs,
and the same data representation,
it's very easy to alternate
between the two.
Once you've installed the packages,
it's literally just a choice
you make in the drop-down
menu somewhere.
And I actually spent about six months
working on my Character Controller
before trying to switch
to Havok for the first time.
But when I did, everything
worked perfectly on the first try.
I didn't need to change
anything in my code.
Now, just like in most Physics
engines, in DOTS Physics,
you have various APIs
to do Physics queries in the world.
But here's what's cool
about these queries.

Chinese: 
最后，要确保你在高速下有非常精确的
连续碰撞检测，避免这些情况
因此出于这些原因，我制作的这个角色
是一个运动角色
现在，让我们来谈谈在这个项目的上下文中
使用 Unity Physics 和 Havok
这是 Physics 和 DOTS 的两个选项
因为它们共享相同的应用 API 和相同的
数据表示，所以很容易在两者之间切换
一旦你安装了这两个软件包，只需
在某处的下拉菜单选择即可
事实上，我在角色控制器上花了
大约六个月后，第一次尝试切换到 Havok
切换后，第一次尝试就一切顺利
我不需要修改代码中的任何内容
类似大多数 Physics 引擎，在 DOTS Physics 中
可使用各种 API 在世界中进行 Physics 查询
这些查询非常好用

English: 
CastCollider is kind of your equivalent
of BoxCast or SphereCast
and CalculateDistance is as
if OverlapsSphere or OverlapBox
also gave you additional info
about the query
like the normal or the distance
between the two colliders.
But both of these queries will work
with any Convex Collider
you give them.
So in the case
of my Character Controller,
that means that the same
code can be used
to handle collisions for any shape.
You could decide, for example,
to have capsule character
or a cylinder character,
or a long, horizontal box.
And as you can see here,
everything will work
just as you'd expect in all cases.
You're not just limited
to a capsule character.
Here's another great tool
in DOTS Physics: Hit collectors.
They're basically like struct
that you pass to your Physics queries
and they'll give you a callback
for each hit that the query finds.
And in this callback, you can say
if you want to accept

Chinese: 
CastCollider 类似 BoxCast 或 SphereCast
CalculateDistance 类似 OverlapsSphere
或 OverlapBox，还提供了查询的额外信息
比如两个碰撞体之间的法线或距离
这两个查询都可以和
任何凸面碰撞体一起使用
所以在我的角色控制器的例子中
这意味着相同的代码可以用于
处理任何形状的碰撞
例如，你可以决定使用胶囊体角色或
圆柱体角色，或者一个长的水平盒体
正如你在这里看到的
一切都将如你所期望的那样运转
你不仅仅局限于胶囊体角色
这是 DOTS Physics 的另一个好工具：命中收集器
它们相当于传递给 Physics 的结构，对于查询
找到的每个命中，都会给你一个回调
在这个回调中，可以根据所需的任何条件

English: 
or reject that hit based on
any conditions you might think of.
So you can use
hit collectors for all kinds
of special hit filtering scenarios,
without having
to first store all the hits
in an array
and then filter them out.
I use them for things like ignoring
the character's own Collider
or ignoring triggers
and backface hits,
or ignoring hit entities that have
a certain component on them.
It's the kind of situation
where simply using
collision filters or layers
would not be enough.
So, hit collectors can give you
a lot of power.
Now let's talk about
simulation modification.
In DOTS Physics,
you have a few opportunities
to modify the Rigidbody simulation
after the contacts are generated
but before they're
actually solved by the engine.
And that means you can do things
like discarding collisions
between two Rigidbodies,
or changing the mass factors
between them,
or even the collision normals
so that they will try to de-collide
in a different direction.

Chinese: 
来决定是接受还是拒绝
因此，你可以将命中收集器用于
各种特殊的命中过滤场景
而不必首先将所有的命中存储
在一个数组中，然后进行过滤
我用它们实现，比如忽略角色自己的碰撞体
或者忽略触发器和背面命中
或者忽略上面有某个组件的命中实体
这种情况下，仅仅使用
碰撞过滤器或层是不够的
因此，命中收集器提供了很多功能
现在我们来谈谈模拟修改
在 DOTS Physics 中，在接触面生成之后
但是在它们被引擎实际解算之前
你有一些机会修改刚体模拟
这意味着你可以做些调整，比如丢弃两个刚体
之间的碰撞，或者改变二者间的质量因子
甚至是碰撞法线，这样它们就可以尝试
从不同的方向去碰撞

English: 
And here's an example of how I use
it in my Character Controller.
If you want your Kinematic
character to be able to stand
on a see-saw like you see here,
and be pushed up by it,
by default, that can't work
because to the Physics engine,
a Kinematic character is considered
to have an infinite mass.
But by intercepting and discarding
some contacts between the see-saw
and the character, and applying
some manual forces,
we can simulate
dynamic interactions.
So this opens up
a lot of possibilities
for ways that Kinematic characters
can have better interactions
with their environments.
Now let's see what this looks like
in practice.
Here we have a capsule character
that can move on slopes
while always sticking
to the ground.
It can move on rough terrain
without ever having its velocity
deviated or slowed down.
And finally, it can stay
on moving platforms

Chinese: 
这有一个我如何在我的角色控制器中使用的例子
如果你想让你的运动角色能够像那样
站在跷跷板上并被它推上来
默认情况下，这行不通，因为对于 Physics 引擎来说
运动角色被认为有无限的质量
但是通过截取和丢弃跷跷板和角色之间的一些接触点
并施加一些手动推力
我们可以模拟动态交互
因此，这为运动角色
与其环境进行更好的互动
开辟了许多可能性
现在让我们看看这在实践中的效果
这里，我们有一个胶囊体角色，可在斜坡上移动
并始终保持在地面
它可以在崎岖的地形上移动
速度不会偏离或减慢
最后，它可以停留在移动平台上

English: 
and move along with it
perfectly well.
And now, when it comes
to performance,
in this test, you see 10,000
Character Controllers
moving on a big terrain mesh
of about 500,000 triangles.
This Scene is running
at about 110 FPS on a gaming laptop
but I'll have the details
in a moment.
So I made this little
performance comparison
between my previous
MonoBehavior character
and my new DOTS character
who are both doing
about the same amount
of calculations
and physics queries every frame.
In both cases, I measured
the total frame time
of 10,000 moving characters
in different Scenes
and different hardware
with rendering turned off.
One of the Scenes is them moving
on a big box collider
and the other one is them moving
on the Terrain Mesh you just saw.
And as you can see from
the results, depending on the CPU,

Chinese: 
并完美地与它一起移动
现在，我们看看性能，在这个测试中
你看到 10,000 个角色控制器在一个大约有
500,000 个三角形的大型地形网格上移动
这个场景在一台游戏笔记本电脑上以大约 110 FPS
的速度运行，我会马上知道细节
我在之前的 MonoBehavior 角色和
新的 DOTS 角色之间
进行了一个小的性能比较
这两个角色在每一帧都进行了
相同数量的计算和物理查询
在这两种情况下，我测量了在渲染关闭的情况下
不同场景和不同硬件下
10,000 个移动角色的总的帧时间
一个场景是在一个大的盒型碰撞体上移动
另一个场景是在刚才的地形网格上移动
从结果中可以看出，根据 CPU 的不同

English: 
the DOTS version performs
around 10 to 20 times better.
So that conclude my talk on
Character Controllers and DOTS,
I hope you enjoyed it,
and if you want to stay informed
about the advancement of this
project or eventual release dates,
the best way to do that
would be to follow my Twitter
which is on screen at the moment.
[STEVE] So that wraps up our jaunt
through some of the features
in the Unity Physics package.
Please come and join us
at the DOTS Physics forum,
it's got an active amount
of discussion going on there.
And thank you for your time.
Hopefully it was worth it.
♪ [MUSIC] ♪

Chinese: 
DOTS 的性能提升了 10 到 20 倍
我关于角色控制器和 DOTS 的演讲到此结束
我希望你喜欢，如果你想了解这个项目的
进展或者最终的发布日期
最好的方法是关注
屏幕上给出的我的 Twitter
[STEVE] 这就结束了我们在 Unity Physics 软件包
中的一些功能的概要介绍
请参加我们的 DOTS Physics 论坛
那里正在进行热烈的讨论
谢谢参加本次讲座，希望您有所收获。
♪ [音乐] ♪
