[Unity]如何解决带刚体的物体在墙角会穿墙的问题

问题背景

当一个物体在两个带碰撞体的方块组成的墙角时,只要”挤一挤”就可以从墙角穿墙而过:

[Unity]如何解决带刚体的物体在墙角会穿墙的问题
[Unity]如何解决带刚体的物体在墙角会穿墙的问题

原因分析

根据【Unity】Rigidbody.velocity 的陷阱一文,有以下结论:
使用 transform.Translate(), transform.RotateAround(), rigidbody.MovePosition(), Vector3.MoveTowards() 等方法 “强制” 改变刚体的运动状态时,此时物体速度的改变并不会引发 Rigidbody.velocity的改变,

  • 如果仅使用 MovePosition()控制物体移动(称之为”仅移动”),刚体组件的 velocity会一直为0
  • 如果仅使用 AddForce()控制物体移动(称之为”仅受力”),它的 velocity与真实速率一致
  • 如果同时使用 MovePosition()AddForce()控制物体移动,它的真实速率是”仅移动”和”仅受力”的效果之和,但 velocity的数值和”仅受力”时一致

也就是说,物理系统只能理解由 velocity的变化而产生的运动(施加力->产生加速度->产生速度/直接修改 velocity),当对一个由物理系统控制的刚体使用物理系统以外的方法施加运动时,物理系统就无法正确处理该物体的物理行为了,而上述的穿墙bug也正是因为角色本身的移动是由 MovePosition()控制的,导致物理系统无法正确处理在墙角处的碰撞判定

解决方案

通过修改 velocity来实现角色移动:

    private void Move() {
        var speed = _properties.speed; //在编辑器中设置的角色的速度
        var verAxis = Input.GetAxisRaw("Vertical");
        var horAxis = Input.GetAxisRaw("Horizontal");
        Vector3 input = new Vector3(horAxis, 0, verAxis);
        _rigidbody.velocity = input * speed;
    }

注意事项

transform.Translate()可能比较好理解,毕竟是通过直接修改 transform组件来完成的运动,物理系统无法理解很正常,但是为什么 rigidbody.MovePosition()也不行呢?翻一翻官方文档可以发现,Unity官方对这个方法的描述是:

[Unity]如何解决带刚体的物体在墙角会穿墙的问题
“移动 kinematic刚体到指定位置”,即该方法仅作用于运动学刚体,即不受物理系统控制,需要由各种变换方法直接控制物体移动的刚体,不适用于普通的遵循力学规律的刚体。

Original: https://www.cnblogs.com/m1ds/p/16034873.html
Author: m1ds
Title: [Unity]如何解决带刚体的物体在墙角会穿墙的问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/619561/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Django配置redis缓存

    Django配置redis缓存 (1)首先安装django-redis pip install django-redis (2)在settings中配置如下所示: 改配置仅为示例,…

    数据库 2023年6月14日
    090
  • Centos7安装Docker

    一、docker运行流程 举个例子你想使用MySQL镜像,那么执行docker pull 下载镜像的时候 首先它会在本地仓库进行运行,如果本地仓库有你想要的MySQL镜像 那么它会…

    数据库 2023年6月14日
    0117
  • 9.回文数

    给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文,而…

    数据库 2023年6月16日
    067
  • Linux 系统安装RocketMQ

    准备工作 1.去官网下载一个安装包 1.解压 unzip rocketmq-all-4.9.0-bin-release.zip -d /download/compress/ 2.进…

    数据库 2023年6月6日
    087
  • ShardingSphere-JDBC进行分库分表

    一、前言:分库分表 在大型的互联网系统中,可能单台MySQL的存储容量无法满足业务的需求,这时候就需要进行扩容了。 和之前的问题一样,单台主机的硬件资源是存在瓶颈的,不可能无限制地…

    数据库 2023年6月14日
    071
  • B树-删除

    B树系列文章 1. B树-介绍 2. B树-查找 3. B树-插入 4. B树-删除 删除 根据B树的以下两个特性 每一个非叶子结点(除根结点)最少有 ⌈ m/2⌉ 个子结点 有k…

    数据库 2023年6月14日
    073
  • MySQL–创建计算字段

    存储在数据库表中的数据一般不是应用程序所需要的格式。下面举几个例子。  如果想在一个字段中既显示公司名,又显示公司的地址,但这两个信息一般包含在不同的表列中。  城市、州和邮政…

    数据库 2023年6月16日
    089
  • JDK1.7-HashMap原理

    JDK1.7 HashMap JAVA技术交流群:737698533 如何在源码上添加自己的注释 打开jdk下载位置 解压src文件夹,打开idea, ctrl+shift+alt…

    数据库 2023年6月16日
    077
  • 如何本地navicat连接虚拟机安装的linux 的mysql

    2022.3.20 如何本地连接虚拟机安装的linux 的mysql 1防火墙开启开启 1.1、开启端口3306 1.2、重启防火墙 1.3查看已经开放的端口: 如果mysql 密…

    数据库 2023年5月24日
    075
  • Flume和 Sqoop

    vim flume-dir-hdfs.conf 添加如下内容 a3.sources = r3 a3.sinks = k3 a3.channels = c3 Describe/con…

    数据库 2023年6月16日
    087
  • JUC自定义线程池练习

    JUC自定义线程池练习 首先上面该线程池的大致流程 自定义阻塞队列 首先定义一个双向的队列和锁一定两个等待的condition 本类用lock来控制多线程下的流程执行 take和p…

    数据库 2023年6月11日
    097
  • Windows安装mysql数据库

    一般我安装mysql用以下两个方法: 一.phpstudy环境下的mysql安装 只需将mysql的bin目录配置到系统环境变量即可, 输入默认密码root即可登录 二.本地直接安…

    数据库 2023年5月24日
    086
  • Java的Lambda表达式

    函数式编程(Functional Programming)是把函数作为基本运算单元,函数可以作为变量,可以接收函数,还可以返回函数。历史上研究函数式编程的理论是Lambda演算,所…

    数据库 2023年6月9日
    098
  • Windows 装机必备

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    数据库 2023年6月6日
    074
  • Docker Bridge 网络原理

    Docker 的网络子系统是可插拔驱动式的,默认情况下存在或支持多种网络接口,如 bridge、host、overlay、macvlan 以及 none 类型的网络接口。 brid…

    数据库 2023年6月6日
    090
  • 2022的七夕,奉上7个精美的表白代码,同时教大家快速改源码自用

    🤵‍♂️ 个人主页:奇想派👨‍💻 作者简介:奇想派,十年全栈开发经验,团队负责人。喜欢钻研技术,争取成为编程达人 🎖️!🗺️学海无涯苦作舟,🛤️编程之路无悔路!📝 如果文章对你有帮…

    数据库 2023年6月16日
    0109
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球