第二十五章 刚体Rigidbody

news2024/12/23 0:45:01

在物理学中,静止和匀速直线运动是物体的平衡状态,如果给该物体施加某一个力的话,物体的平衡状态就会改变,当然这个真理的前提是理想状态。我们知道在现实世界中,由于重力和摩擦力的存在,任何一个物体都不可能永无止境的运动下去。因此,要想让物体保持运动状态,我们就必须持续的给物体施加一个力。在Unity中就模拟了这种效果,它是通过一个叫做“Rigidbody刚体”的组件实现的。接下来,我们就来创建一个“PhysicsDemo”3D工程来介绍Rigidbody刚体组件。

首先,我们创建了一个平面,然后在平面的上方创建了一个球体。

接下来,我们就给球体添加刚体Rigidbody组件。添加操作非常简单,可以在球体的Inspector检视视图下面点击“Add Component”。

我们在搜索框中输入“ri”,就会在下拉框中就能看到“Rigidbody”组件,注意不要选择“Rigidbody 2D”,这个虽然也是刚体,但是它是用于2D游戏对象的。我们是这里要选择的是3D的“Rigidbody”组件。

在“Rigidbody”刚体组件下有很多参数,我们暂时先不介绍,直接运行工程来查看添加刚体组件后的球体会有什么效果。如下所示:

运行后,我们发现球体直接落到了平面上面。这是因为,给球体添加刚体组件后,球体就会受到“重力”的作用,沿着Y轴方向向下掉落,直到碰到平面而停止。这个“重力”就是“Rigidbody”刚体组件产生的效果。刚体会接管附加到的游戏对象的运动,如果我们施加一个力来推动游戏对象的话,Unity会自动计算该游戏对象的运行效果。如何施加一个力呢?我们点击菜单栏“Component”->“Physics”->“Constant Force” 恒定力组件。

 

我们在“Constant Force” 恒定力组件的Force参数的X值修改为2,也就是在X轴方向上施加数值为2的一个力来作用于当前球体。我们运行工程,查看效果。

我们发现球体受到重力作用掉落后,还同时受到X轴方向的力而向右继续运动。但是,有时候我们不希望游戏物体以这样的方式运行,因此我们需要游戏对象的运动摆脱Unity物理引擎的控制。刚体组件有一个名为 Is Kinematic 的属性,该属性可以让刚体摆脱物理引擎的控制,并允许通过脚本以运动学方式来移动刚体。接下来,我就来讲解刚体的一些参数。

Mass             游戏对象的质量(默认单位为千克)。

Drag              游戏对象移动时受到阻力的大小,0 表示没有阻力。

Angular Drag  游戏对象旋转时受到阻力的大小,0 表示没有角阻力。

Use Gravity    如果启用此属性,则对象将受重力影响。默认是启用状态。

Is Kinematic   如果启用此选项,则对象将不会被物理引擎驱动,上文中已经提到。

Interpolate      仅当在刚体运动中看到抖动时才尝试使用提供的选项之一。

                        - None    不应用插值。

                        - Interpolate   根据前一帧的变换来平滑变换。

                        - Extrapolate  根据下一帧的估计变换来平滑变换。

Collision Detection 用于防止快速移动的对象穿过其他对象而不检测碰撞。

Discrete为默认值,表示对场景中的所有其他碰撞体使用离散碰撞检测。

Constraints     对刚体运动的限制,可以限制在X/Y/Z某一轴向上移动或旋转。我们展开下面有两个子项,分别是冻结位置和冻结旋转,每一个冻结子选项都分为X,Y,Z三个轴向的冻结。如果当刚体操作游戏物体运动的时候,不会在这些轴向上产生移动或旋转。

在上面的案例中,我们使用“Constant Force” 恒定力组件给球体施加一个力,让其产生运动。如何使用脚本来使用刚体控制物体运动,或者说如何使用脚本给游戏对象施加一个力呢?首先,我们先取消“Constant Force” 恒定力组件,如下所示

我们只需要取消“Constant Force”组件前面的勾选项即可。接下来,我们创建一个脚本SphereScript.cs,然后附加到球体上面,代码如下所示

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SphereScript : MonoBehaviour
{
    // 刚体组件
    private Rigidbody rbody;

    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            rbody.AddForce(Vector3.right * 100);
        }
    }
}

上述代码就是,当我们按下键盘A键的时候,使用刚体的AddForce方法给球体施加一个Vector3.right方向,大小为100。这里需要注意的是,AddForce施加的力在 FixedUpdate 中计算,而FixedUpdate时间间隔一般是0.02秒。代码完成之后,我们还需要做一个非常关键的设置,就是取消Use Gravity,如下所示

这样,球体就不再受重力影响掉落到平面上面了。我们可以Play运行一下。

我们发现,球体不再掉落下来,并且当我们按下A键的时候,球体向右开始移动。我们知道,移动的物体,最重要的是速度。当我们给物体施加一个力的时候,这个速度与力的关系是如何呢?我们修改一下代码,打印刚体的速度velocit 值。

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            rbody.AddForce(Vector3.right * 100);
        }
        Debug.Log(rbody.velocity);
    }

我们增加一个日志,输出游戏物体的速度。我们重新Play工程

我们发现,当我们施加一个力的时候,球体开始运动,X轴向速度是2.0。这个数值是怎么计算得来的呢?首先了解一下动量定理:物体在一段时间Δt内的动量变化量等于它在这个过程中所受力的冲量,也就是力与力的作用时间的乘积,数学表达式为:FΔt = mΔv 。其中F就是这个力的大小,Δt就是这段时间,m就是物体的质量,Δv表示这段时间的平均速度。我们球体对象的质量mass为1(在Rigidbody组件中设置的),然后给它一个X轴正方向大小为100的力。AddForce方法还有第二个参数ForceMode,代表施加力的类型。ForceMode为枚举类型,有4个枚举成员:ForceMode.Force,ForceMode.Acceleration,ForceMode.Impulse,ForceMode.VelocityChange。

他们代表的含义如下所示:

ForceMode.Force 默认方式,使用刚体的质量计算,以每帧间隔时间为单位计算动量。我们上面已经说了FixedUpdate按0.02s秒计算,则由动量定理公式FΔt = mΔv可得, 速度v =  FΔt / m = 100 * 0.02 / 1 = 2.0米/秒。也就是说,刚体1秒移动2米的距离。

ForceMode.Acceleration表示忽略游戏对象的质量(相当于质量固定为1)。

ForceMode.Impulse 表示采用瞬间力作用方式,即把Δt的值默认为1,速度会变快。

ForceMode.VelocityChange 表示忽略质量和时间(两者均固定为1),速度就更加快了。

最后,我们要讲解一下刚体的阻力Drag值。在现实世界中,物体移动一定会受到阻力的影响,其速度会慢慢减少,最终停止运动。在Unity中,为了能够让物体运动一段距离后停止,我们可以给刚体组件增加阻力Drag值。接下来,我们给刚体增加1的阻力值。

然后,我们在重新Play工程,查看日志中速度的变化。

我们发现,刚体的速度从2.0开始依次减少0.1的速度。阻力与速度之间的公式是什么呢?网上查询了PhysX得知:velocity = velocity * ( 1 - deltaTime * drag); 也就是说,速度会随着每帧的执行,越来越小,直到为零。假如阻力为1的话,游戏对象会在运动1秒后速度减小到零(静止不动)。也就是说,不管施加的力有多大,当阻力为1的时候,游戏对象都会在1秒后静止。但是,从我们实际的运行情况来看,好像也没有那么的准确。而且,如果发生碰撞的话(球体在平面上),速度也会不断减少。

我们总结一下:刚体可以接受力和扭矩,力可以让刚体对象移动,扭矩可以让刚体对象旋转,向刚体施加力/扭矩实际上会改变对象的变换组件的位置和旋转。我们可以通过刚体的AddForce或AddTorque方法来给游戏对象添加力或者扭矩。但是,在实际开发中,我们可能取消Use Gravity重力影响,勾选Is Kinematic属性,使用代码控制游戏对象平移或旋转变换。两者各有各的优势,刚体可以模拟现实世界的运动效果,而代码控制更加灵活。并且,刚体组件一般都是搭配碰撞体组件一起使用的。另外,当处于休眠模式的刚体收到外界的影响时候,刚体会被唤醒,继续参与物理运算。如果希望通过脚本来控制刚体的休眠状态,可以调用刚体的Sleep和WakeUp方法让刚体进入休眠或者从休眠中唤醒。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/484240.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SQL篇】窗口函数和公共表达式

1077 项目员工 III # Write your MySQL query statement below select project_id, employee_id from (select project_id, e.employee_id, rank() over(partition by project_id order by experience_years desc) as rkfrom Employee ejoin Project pon e.employee_id p.empl…

【Fluent】接着上一次计算的结果继续计算,利用计算过程中得到的物理场(温度、速度、压力等)插值Interpolate文件初始化模型的方法

一、问题背景 因为fluent中支持的初始化无非三种类型。 1、Standard initialization 标准初始化 2、Hybridinitialization 混合初始化 3、FMG initialization FMG初始化 另外&#xff0c;还可以用UDF通过坐标判断的方式予以初始化。 但是这些初始化方法都没办法利用以前计算过…

通关MyBatis(上)

作者&#xff1a;~小明学编程 文章专栏&#xff1a;spring框架 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 什么是MyBatis 如何使用Mybatis 添加依赖 创建数据库 配置数据库连接字符串 MyBatis的操作流程 数据持久层 配置mybatis的xml文件 mapp…

Windows自动虚拟机WSL和VMware虚拟机兼容问题(此平台不支持虚拟化的 Intel VT-x/EPT)

问题背景与原因分析 在安装了WSL2之后&#xff0c;忽然发现VMware Workstation无法正常启动了。就是在开启虚拟机时遇到了这种情况&#xff1a; “ 此平台不支持虚拟化的 Intel VT-x/EPT” 问题描述&#xff1a;出现以上问题&#xff0c;发现WSL2和 VMware Workstation 是不兼…

idea使用git遇到的小问题

idea使用git遇到的小问题 前置说明颜色含义中文插件修改提交的用户名 前置说明 idea版本为2022专业版 github需要自己会科学上网 颜色含义 在idea中使用github后&#xff0c;会发现项目中会有各种各样的颜色&#xff0c;如图所示文件全为绿色 这颜色含义分别为&#xff1a;…

函数-函数递归及练习

目录 1、什么是递归&#xff1f; 2、递归的两个必要条件 3、递归的练习 3.1 接受一个整型值&#xff08;无符号&#xff09;&#xff0c;按照顺序打印它的每一位 3.2 编写函数不允许创建临时变量&#xff0c;求字符串的长度 3.3 求第n个斐波那契数 3.4 字符串逆序&…

UG NX二次开发(C++)-建模-修改NXObject或者Feature的颜色(二)

文章目录 1、前言2、在UG NX中修改Body的颜色操作3、采用NXOpen(C)实现3.1 创建修改对象颜色的方法3.2 在do_it()中添加调用的代码3.3 测试效果 1、前言 在UG NX中&#xff0c;改变NXObject和Feature的操作是不相同的&#xff0c;所以其二次开发的代码也不一样&#xff0c;我们…

企业级信息系统开发讲课笔记4.1 Spring Boot入门程序

文章目录 零、学习目标一、Spring Boot框架概述&#xff08;一&#xff09;由Spring到Spring Boot&#xff08;二&#xff09;Spring Boot框架的核心功能&#xff08;三&#xff09;Spring Boot框架的应用 二、使用Maven方式构建Spring Boot项目&#xff08;一&#xff09;创建…

二维字符数组的三种输入方式浅析(scanf()、gets()和fgets())

二维字符数组的输入 目录 二维字符数组的输入1.scanf函数知识点scanf()关于回车的问题&#xff1a; 2.gets函数3.fgets函数参考链接 1.scanf函数 知识点 按照常规输入数组的办法&#xff0c;通过 for 循环实现 将整个字符串输入时&#xff0c;在数组名前不加&&#xff0…

Java 基础进阶篇(二)—— static 静态关键字与单例模式

文章目录 一、static 静态关键字1.1 静态成员变量与实例成员变量1.2 静态成员方法与实例成员方法1.3 static 访问注意事项1.4 内存使用情况 二、工具类三、代码块四、单例模式4.1 饿汉单例4.2 懒汉单例 一、static 静态关键字 static&#xff1a;代表静态的意思&#xff0c;可…

Java 基础进阶篇(六)—— 接口详解

文章目录 一、接口概述二、接口的基本使用三、接口从 JDK 8 开始新增的方法四、接口的注意事项&#xff08;了解&#xff09;补充&#xff1a;接口与接口的关系 一、接口概述 规范的基本特征是约束和公开。 接口就是一种规范&#xff0c;其约束别人必须干什么事情。 所以&…

【五一创作】Matlab 绘制风速、风向统计玫瑰花图【优化】

在之前&#xff0c;有个博客专门讲matlab 绘制风速、风向统计玫瑰花图&#xff1b;这里面存在不少细节问题&#xff0c;目前对该部分代码做了优化。以前的博客链接见下&#xff1a; Matlab 绘制风速、风向统计玫瑰花图 最近接了一个任务&#xff0c;需要绘制风速、风向的统计玫…

Java 基础进阶篇(五)—— 抽象类与模板方法设计模式

文章目录 一、抽象类、抽象方法概述二、抽象类的特征三、模板方法设计模式3.1使用场景3.2 实现步骤3.3 写作文案例 补充&#xff1a;final 和 abstract 是什么关系? 一、抽象类、抽象方法概述 在 Java 中 abstract 是抽象的意思&#xff0c;可以修饰类、成员方法。 abstract …

Java 基础进阶篇(七)—— 面向对象三大特征之三:多态

文章目录 一、多态的概述二、多态中成员访问特点 ★三、多态的优势与劣势四、多态下的类型转换4.2 自动类型转换&#xff08;从子到父&#xff09;4.2 强制类型转换&#xff08;从父到子&#xff09;4.3 instanceof 关键字 一、多态的概述 多态&#xff1a;是指执行同一个行为…

Java 基础进阶篇(四)—— 权限修饰符、final 关键字与枚举

文章目录 一、权限修饰符二、final 关键字2.1 final 作用2.2 final 修饰变量举例2.3 常量 三、枚举3.1 枚举的格式3.2 枚举的特征3.3 枚举的应用 一、权限修饰符 权限修饰符 用于约束成员变量、构造器、方法等的访问范围。 权限修饰符&#xff1a; 有四种作用范围由小到大 (p…

Java 基础进阶篇(三)—— 面向对象的三大特征之二:继承

文章目录 一、继承概述二、内存运行原理 ★三、继承的特点四、继承后&#xff1a;成员变量和方法的访问特点五、继承后&#xff1a;方法重写六、继承后&#xff1a;子类构造器的特点七、继承后&#xff1a;子类构造器访问父类有参构造器八、this、super 总结 一、继承概述 Jav…

机器学习之利用SMO算法求解支持向量机—基于python

大家好&#xff0c;我是带我去滑雪&#xff01; 本期将讨论支持向量机的实现问题&#xff0c;我们知道支持向量机的学习问题可以化为求解凸二次规划问题。这样的凸二次规划问题具有全局最优解&#xff0c;并且有许多最优化算法可以用于这一问题的求解。但是当训练样本容量很大…

【C++】 探索程序 详细解读程序在运行过程中都发生了什么

目录 头文件-源代码 头文件重复包含 问题 解决方案 程序生成过程 预处理Preprocessi 编译Compilation 汇编Assembly 链接Linking 编译期-运行期 编译期确定 运行期确定 编译期错误 运行期错误 类和对象 宏 宏的其他用法 inline内联 头文件-源代码 头文件&…

Vue简介和常用指令

概述&#xff1a; MVVM思想&#xff1a;视图层数据和数据模型里面的数据发生变化都会影响到另一边的数据&#xff0c;通过ViewModel自动实现。 Vue入门案例 步骤&#xff1a; 上面提到了数据模型和试图层的数据是关联的&#xff0c;此处数据模型里面el的值就是选择了哪一个视…

jQuery引入----练习

jQuery引入----练习 html <!DOCTYPE html> <html><head><title>jQuery引入</title><!-- css样式引入 --><link rel"stylesheet" href"../css/a.css"><!-- jquery函数库引入 --><script type"tex…