刚体

article/2025/10/20 14:06:24

概述

在整个 Unity 物理系统中,最重要概念就是刚体 Rigidbody

刚体是物理学中的概念,它是指在运动中和受力后,形状和大小不变,并且内部各点相对位置不变的物体。刚体是一种为了方便物理计算而提出的理想化模型,在不需要考虑物体本身的形变时,可以把物体当做刚体进行处理。

在 Unity 中,提供了 Rigidbody 组件,用来模拟刚体,我们叫它刚体组件。给游戏对象添加刚体组件,就能够使游戏对象受到碰撞弹开、能够受到重力下落、能够给其它刚体施加力等。所以刚体组件的主要作用就是:

使游戏对象能够受力和施力

刚体组件

Mass 质量:用来模拟物体的质量,单位为千克。质量会影响惯性大小,而且质量不同的两个刚体相互碰撞时,它们各自的反应也不同。要注意物体的质量大小不会影响自由落体时的速度,想想伽利略的两个铁球同时落地。

Drag 空气阻力:物体受力移动时受到的空气阻力大小,0 表示没有空气阻力。如果想让两个物体自由落体时速度不同,就给它们设置不同的空气阻力。空气阻力越大,物体感觉起来就越轻,比如铁块的空气阻力可以设置为 0.001,羽毛的空气阻力可以设置为 10。这个值一般不需要设置,如有特殊需要的话,就参考铁块和羽毛的阻力范围进行设置。

Angular Drag 角阻力:物体受力旋转时受到的空气阻力大小。因为物体旋转时的速度叫做角速度,所以旋转时受到的阻力就叫做角阻力。这个属性和 Drag 空气阻力属性类似, Drag 空气阻力属性会影响物体在空气中移动时的速度,Angular Drag 角阻力会影响物体在空气中旋转时的速度。

Use Gravity 启用重力:物体是否受重力影响。受重力影响的物体会进行自由落体。

Is Kinematic 运动学:如果我们只是需要让物理系统进行碰撞检测,不需要使用物理系统控制游戏对象,而是在脚本中使用 Transform 控制物体,此时我们可以勾选刚体组件中的 Is Kinematic 属性。

Interpolate 插值:物体在进行物理运动时的插值方式,默认是 None 不使用插值。

-None 不使用插值:这个选项是默认值,一般情况下此选项不需要设置。如果物体在物理系统控制下,会发生轻微的抖动,可以尝试使用另外两种选项。

-Interpolate 插值:这个选项会根据上一帧中物体的 Transform 来计算当前帧的插值。

-Extrapolate 向后推断:这个选项会推断下一帧中物体的 Transform 来计算当前帧的插值。

Collision Detection 碰撞检测:碰撞检测模式,默认是 Discrete 离散检测。

- Discrete 离散检测:对场景中的其它碰撞体使用离散碰撞检测。一般情况下我们不需要修改此属性。物理系统默认的碰撞检测是离散的,所以有时高速移动的刚体会穿透障碍物,此时我们才需要使用另外两种碰撞检测模式。

- Continuous 连续检测:刚体对其它没有刚体的碰撞器采用连续检测,防止刚体速度过快穿透障碍物。比如快速飞行的子弹碰撞静止的墙壁,此时如果采用 Dscrete 离散检测,子弹不会打在墙壁上反弹,而是会穿透墙壁。但该模式下并不能正确检测两颗高速飞行的子弹相互碰撞,因为它们两个都带有刚体,此时请使用第三种模式。要注意连续检测会影响物理性能,非必要情况请使用默认的 Discrete 离散碰撞检测。

- Continuous Dynamic 连续动态检测:会对其它刚体(碰撞检测模式不能是 Discrete 离散碰撞检测)进行连续检测,防止互相穿透。对没有刚体的碰撞器也会采用连续碰撞检测

Constraints 限制:对刚体的运动进行限制。

- Freeze Position 冻结位移:当刚体移动时,可选地忽略在某个轴上的位移。有 3 个可勾选属性 X、Y、Z,分别表示在 X 轴、Y 轴和 Z 轴方向上的位移。如果勾选了 Y 则表示,刚体受力运动后,不会在 Y 轴方向上发生位移。

- Freeze Rotation 冻结旋转:当刚体旋转时,可选地忽略绕某个轴的旋转。也有 3 个可勾选属性,分别表示绕 X 轴旋转、绕 Y 轴旋转和绕 Z 轴旋转。如果勾选了 X 则表示,刚体受力运动后,不会绕 X 轴发生旋转。

物理系统和 Transform

在 Unity 中,控制游戏对象有两种方式:一种是直接使用 Transform,比如 Transform.Position 或者 Transform.Rotation 等;另一种方式就是给游戏对象添加刚体,通过物理系统控制游戏对象。

需要注意的是,一旦给游戏对象添加了刚体组件,那么这个游戏对象的运动会由物理系统负责计算。此时不要在脚本中直接使用 Transform.Position 或者 Transform.Rotation 等代码直接修改游戏对象的位置和旋转,否则会导致物理计算结果不正确。也就是说,使用物理系统控制的游戏对象,不要直接修改 Transform 属性。

这是因为物理系统会根据刚体的受力情况,计算出每一帧物体的正确位置以及旋转,然后改变物体的 Transform。此时如果我们通过代码强行修改 Transform 的属性,最终会导致物体的运动不正确,或无法正确地碰撞。

使用物理系统时,如果在脚本中需要控制刚体,可以使用刚体的 void AddForce (Vector3) 方法,给刚体施力使刚体移动,或者使用刚体的 void AddTorque (Vector3) 方法,给刚体施加力矩使刚体产生旋转。如果需要让刚体相对精确地移动和旋转,可以使用刚体的 void MovePosition (Vector3)方法,移动刚体的位置,或者使用 void MoveRotation (Quaternion) 方法,旋转刚体。

如果我们只是需要让物理系统进行碰撞检测,不需要使用物理系统控制游戏对象,而是在脚本中使用 Transform 控制物体,此时我们可以勾选刚体组件中的 Is Kinematic 属性。

在使用刚体时还有一个需要额外注意的就是刚体的大小。场景中的刚体要保证它的大小,或者说缩放比例是合适的。一个鸡蛋大小的球体和一个月球大小的球体,自由下落时看起来效果是不一样的,尽管它们两个下落速度相同,但更大的物体下落时,在感官上会觉得下落速度很慢。所以如果感觉场景中物体的物理效果不对时,也要先检查一下物体大小是否正确。

刚体组件的属性

在脚本中,我们可以使用 GetComponent<Rigidbody> () 方法获取当前游戏对象身上的刚体组件,当然前提是它有这个组件。

除了这行代码以外,其它关于

物理控制的代码都建议放在 void FixedUpdate () 方法中完成

不建议在 void Update () 方法中。因为 Update 方法是帧更新,也就是场景中视图的更新,帧更新的速度并不稳定并且频率比 FixedUpdate 方法低。将物理控制代码放在 FixedUpdate 中能够保证物理效果的及时处理,这样等到每次帧更新时,场景中的刚体都会是正确的位置和旋转。

获取到刚体组件后,我们可以通过代码给它施加力、力矩,或者改变它的位置、旋转,或者直接修改它的速度、角速度等。不过首先我们看看刚体属性面板中的这些属性,如何通过代码进行修改。

其中 constraints 属性比较特殊,它是一个枚举类型,表示刚体运动时限制的位移或旋转轴。它的值可以通过按位或运算进行状态叠加,比如我们只需要限制 PositionXPositionZ,其它的都不限制,那么可以这样写,两个枚举值中间进行按位或运算(|)。

位置和旋转

刚体最常用的功能就是以物理的方式控制游戏对象的运动,所以 Rigidbody 中有一些与位置、旋转相关的属性和方法。

其中用来控制刚体位置的有一个 position 属性和一个 MovePosition 方法,用来控制刚体旋转的是 rotation 属性MoveRotation 方法

使用 transform.position 或者 transform.rotation 也可以控制位移和旋转, rigidbody.positionrigidbody.rotation 使用方式和 Transform 没太大区别,不一样的是 Rigidbody 这两个属性修改后,会直接在下一次物理循环中更新 Transform,响应速度更快一些,能保证物理效果的正确性。

rigidbody.MovePosition () 方法和 rigidbody.MoveRotation () 方法更适合FixedUpdate 中连续移动或旋转物体。这两个方法会考虑刚体的插值设置,在连续运动时减少抖动。如不需要连续运动想直接瞬移物体,就使用 rigidbody.positionrigidbody.rotation 属性。连续移动并旋转刚体的例子如下。

力和速度

除了直接修改刚体的位置和旋转以外,我们也可以给刚体施力让它产生运动。力是矢量,所以一般用 Vector3 表示一个力的方向和大小。在脚本中有四种方法给刚体施力。

最常用的是 AddForce 方法。它直接给刚体的质心(质量中心,默认是几何中心)施加力,并且这个力会以世界坐标系进行处理。如果我们参数填写的是 Vector3.forward * 10f,那么这个力的方向就是世界坐标系中 Z 轴正方向,大小是 10。

如果我们需要让这个力以刚体本地坐标系进行处理,可以使用 AddRelativeForce 方法。它的使用方式和 AddForce 方法完全一样,唯一不同的就是,这个方法会把参数中设置的力,以刚体的本地坐标系进行处理,而不是世界坐标。如果我们使用这个方法,参数填写的是 Vector3.forward * 10f,那么这个力的方向就是刚体本地坐标系中 Z 轴正方向,大小是 10。

我们也可以不把力施加到刚体的质心,使用 AddForceAtPosition 方法可以在指定的位置向刚体施力。此时第一个参数表示力的大小和方向,第二个参数就是施力的位置,这两个参数都是以世界坐标系进行处理的。除此以外这个方法使用起来和 AddForce 方法一样。

如果我们要模拟爆炸时周围物体都被炸飞的效果,可以使用 AddExplosionForce 方法添加爆炸力。方法至少需要三个参数,分别表示力的大小(float)、爆炸中心位置(世界坐标系 Vector3)和爆炸的有效半径(float)。添加爆炸力的方法需要由刚体实例来调用,爆炸发生时需要让哪些刚体炸飞,那么这些刚体都需要在同一时间调用这个方法,传递相同的参数。

爆炸发生时,会以爆炸中心位置和爆炸有效半径限定一个球形范围,若刚体在此范围内则会受到一个力的影响,力的方向是从爆炸中心指向刚体质心的向量,力的大小决定于刚体和爆炸中心的距离。

使用爆炸力时,还有可选的第 4 个参数,upwardsModifier。它是 float 类型,默认值为 0。表示在爆炸发生时计算受力方向,会将爆炸中心点位置的 Y 值,往负方向移动多远。比如此参数设置为 2 时,爆炸看起来的位置就在实际位置向下 2 单位,最终的爆炸效果会把周围刚体都向上炸飞。这个参数只会影响爆炸方向,不会影响力的大小。

以上四种添加力的方法都还有一个可选参数,ForceMode 枚举类型参数,施力模式。默认值都是 ForceMode.Force 表示以力的方式施加。另外还有 3 个枚举值,我们可以根据需要设置施力模式。

加速度模式 ForceMode.Acceleration在此模式下,Vector3 类型的参数不再表示力的方向和大小,而是表示加速度的方向和大小(加速度也是矢量)。

此时会直接给刚体添加一个加速度。设置了加速度之后,假设当前帧刚体速度是 v1,那么等到下次物理帧刷新时刚体的速度就是 v2,而 Δt 则是 Time.deltaTime

冲量模式 ForceMode.Impulse在此模式下,Vector3 类型的参数也不再表示一个力,而是一个冲量。

设置冲量可以给物体一个瞬时冲击力,而且要注意冲量的作用效果和物体的质量相关,给不同质量的物体设置相同的冲量,作用效果是不一样的。

速度模式 ForceMode.VelocityChange在此模式下,Vector3 类型的参数直接表示一个速度。

以上三种模式并不常用到,但有些特殊的物理相关的游戏中也许有用。直接给刚体添加冲量或加速度能更容易实现某些物理效果,而不需要我们手动计算力或者速度大小。

力矩也是物理学中的概念,用来描述物体受力旋转的矢量。力矩的方向垂直于旋转平面。我们可以直接给刚体添加力矩使之旋转。

使用 AddTorque 方法或者 AddRelativeTorque 方法,它们两个的区别在于坐标系不同。

我们也可以使用更直观的方式,直接控制刚体的速度或者角速度,角速度的方向也是垂直于旋转平面的。但不建议直接对速度和角速度进行修改,因为这有可能导致物理效果不真实。在某些特殊情况下,我们需要让速度或角速度立即生效,此时可以直接修改速度属性。

一般情况下,我们使用 AddForce 等相关方法施加力或者控制速度,使用 AddTorque 方法控制旋转或者角速度,用 MovePositionMoveRotation 方法连续精确地控制位移和旋转。除了这些常用的属性和方法,还有一些不常用的,比如设置质心的位置、设置最大角速度(默认值是 7)、刚体的休眠和唤醒(默认系统自动完成)、获取刚体上某一点的瞬时速度等。

(The End)


http://chatgpt.dhexx.cn/article/oH06RaqK.shtml

相关文章

技术人员如何从容转型项目经理?

科技在发展&#xff0c;时代在进步&#xff0c;项目越来越复杂&#xff0c;越来越多的技术人员面临技术转型&#xff0c;那么&#xff0c;如何成功转型成了众多技术人员面临的新挑战。 首先我们必须要搞清楚&#xff0c;为什么需要技术人员转型项目经理&#xff1f;项目经理不…

阿里云杨国彦:云上护航,陪伴成长

以下整理自杨国彦在云栖大会“云上成就创新梦想”论坛中发表的《云上护航&#xff0c;陪伴成长》的主题演讲&#xff09; 11月5日&#xff0c;以“云上成就创新梦想”为主题的中小企业云上创新论坛在浙江杭州云栖小镇举行&#xff0c;论坛聚集政府、资本、媒体、机构等相关领导…

滴滴技术专家任玉刚:让你的职业迷茫从哪来回哪去

今天给大家推荐的是《Android开发艺术探索》的作者&#xff08;滴滴技术专家&#xff09;任玉刚老师的直播课&#xff0c;感兴趣的同学可以通过文末的方式参与本次活动&#xff08;喜欢的同学欢迎转发&#xff09;。 我是任玉刚&#xff0c; 我来我想说。 01 收到过无数同学的…

从菜鸟到资深工程师的进阶之路

专访任玉刚&#xff1a;从菜鸟到资深工程师的进阶之路 发表于 2015-12-22 08:25| 11131次阅读| 来源 CSDN| 31 条评论| 作者 夏夏 专访 iOS Android 任玉刚 开发者 CSDN博客 allowtransparency"true" frameborder"0" scrolling"no" src"h…

kafka sasl_ssl配置

一、切换到存储证书的路径 我这里在家目录中的创建了ssl文件夹 mkdir ssl && cd ssl 二、生成服务端密钥库 keytool -keystore server.keystore.jks -alias localhost -validity 365 -genkey验证证书&#xff1a; keytool -list -v -keystore server.keystore.jks …

KAFKA SASL配置 记录

kafka配置SASL 第1步 将kafka_client_jaas.conf/kafka_server_jaas.conf/kafka_zoo_jaas.conf三个文件放入kafka的config文件夹中&#xff0c;文件中配置用户&#xff0c;superadmin用户必须配置。 kafka_client_jaas.conf内容如下 KafkaClient { …

WIN10 VS2019 编译Cyrus SASL

环境 下载安装Visual Studio 2019 安装时在【工作负载】必须勾选【使用C的桌面开发】下载cyrus-sasl源码 从Github上clone或者下载zip包&#xff0c;我本来是需要2.1.26&#xff0c;但是从从https://www.cyrusimap.org/releases/下载对应版本的源码包编译都有问题&#xff0c;…

Kafka3.0 SASL安全认证

下面主要介绍Kafka两种认证方式 kafka验证方式&#xff1a; SASL/PLAIN&#xff1a;不能动态添加用户配置文件写死账号密码 SASL/SCRAM&#xff1a; 可以动态的添加用户 SASL/PLAIN方式 cd /usr/local/kafka/kafka_2.12-3.0.1/bin/ ## 复制一份saslcp kafka-server-start.…

集成OpenLDAP与Kerberos实现统一认证(三):基于SASL/GSSAPI深度集成

文章目录 1. 写作背景2. 既定目标3. 重要概念3.1 SASL3.2 GSSAPI3.3 SASL与GSSAPI的关系3.4 saslauthd3.5 Kerberos化 4. 核心原理4.1 基于SASL/GSSAPI实现Kerberos账号登录OpenLDAP4.2 基于olcAuthzRegexp规则映射Kerberos与OpenLDAP账号4.3 基于saslauthd进行委托认证 5. 安装…

kafka sasl java_Kafka安装及开启SASL_PLAINTEXT认证(用户名和密码认证)

前些日子要封装一个kafka的客户端驱动&#xff0c;配置了下kafka环境&#xff0c;发现配置复杂度完爆rabbitmq很多倍啊&#xff0c;而且发布订阅模式使用起来也很麻烦&#xff0c;可能就胜在分布式了吧。 kafka需要java环境&#xff0c;自行安装java sdk 1.8. 官方加载安装包&a…

go kafka 配置SASL认证及实现SASL PLAIN认证功能

用户认证功能&#xff0c;是一个成熟组件不可或缺的功能。在0.9版本以前kafka是没有用户认证模块的&#xff08;或者说只有SSL&#xff09;&#xff0c;好在kafka0.9版本以后逐渐发布了多种用户认证功能&#xff0c;弥补了这一缺陷&#xff08;这里仅介绍SASL&#xff09;。 本…

kafka集群开启sasl认证

kafka集群开启sasl认证 sasl认证 sasl 是扩展C/S模式验证能力的一种认证机制。它可以规范客户端和服务端传输应答和传输内容编码&#xff0c;简而言之sasl决定了认证的规则&#xff0c;即客户端如何存储身份证书、客户端与服务端如何校验密码都由sasl决定。当我们的客户端通过…

mysql sasl_SASL认证失败的原因(authentication failed)

SASL认证失败的原因(authentication failed) (2012-06-15 00:45:43) 标签&#xff1a; 杂谈 authentication failed) SASL认证失败的原因可分为如下几个可能的方面&#xff1a; Permission问题&#xff1a;对系统用户的SASL Auth尤其重要&#xff0c;要保证postfix用户(smtpd)对…

Kafka安全(以SASL+ACL为例)

目录 1 Security2 SASLACL实现用户及权限认证2.1 下载2.2 Kafka服务配置2.3 修改Kafka 服务启动脚本2.4 配置server.properties2.5 启动Zookeeper2.6 启动Kafka 集群2.7 ACL2.7.1 admin2.7.2 生产者2.7.3 消费者2.7.4 sharga用户2.7.5 shargb用户2.7.6 说明 2.8 生产者客户端代…

安装sasl出错

场景&#xff1a;python项目需要用到 pyhive0.6.4 pyhdfs0.2.2 thrift0.13.0 thrift_connector0.12 thrift_sasl0.3.0进项镜像构建时&#xff0c; 报错&#xff1a;error: command gcc failed with exit status 1 解决方法&#xff1a; 1.ubuntu系统&#xff1a; sudo apt-…

sasl认证原理

SASL - 简单认证和安全层 SASL是一种用来扩充C/S模式验证能力的机制认证机制, 全称Simple Authentication and Security Layer. 当你设定sasl时&#xff0c;你必须决定两件事&#xff1b;一是用于交换“标识信 息”&#xff08;或称身份证书&#xff09;的验证机制&#xff1…

kafka sasl java_Kafka 集群配置SASL+ACL

** Kafka 集群配置SASLACL 测试环境&#xff1a;** 系统: CentOS 6.5 x86_64 JDK : java version 1.8.0_121 kafka: kafka_2.11-1.0.0.tgz zookeeper: 3.4.5 ip: 192.168.49.161 (我们这里在一台机上部署整套环境) kafka 名词解析&#xff1a; Broker: Kafka 集群包含一个或多个…

kafka sasl java_Kafka SASL 安全认证

java client 中添加 SASL 设置信息: Java client consumer properties配置.png 注意 sasl.jaas.config 配置中的分号必不可少。 package kafka; import java.time.Duration; import java.util.Arrays; import java.util.Properties; import org.apache.kafka.clients.consumer…

SASL讲解,以及在Spark中的应用

是什么? SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。在Postfix可以利用SASL来判断用户是否有权使用转发服务,或是辨认谁在使用你的服务器。      SASL提供了一个通用的方法为基于连接的协议增加验证支持,而XMPP使用了一…

关于SASL的介绍文档

http://docs.sun.com/app/docs/doc/819-7056/6n91eac4q?lzh&aview 简单验证安全层 (Simple Authentication Security Layer, SASL) 介绍 SASL 为应用程序和共享库的开发者提供了用于验证、数据完整性检查和加密的机制。开发者可通过 SASL 对通用 API 进行编码。此方法避免…