[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)

大家都在看

  • 设计模式之(4)——单例模式

    定义:单例模式属于创建型模式,该类负责创建自己的对象实例,并且确保只有单个对象被创建,同时该类提供了一种全局访问其唯一实例对象的方式;这个定义中有三个要点:1、单例类只能有一个实例…

    数据库 2023年6月14日
    076
  • IO流思维导图

    IO流思维导图 IO思维导图总结 总览: 1.文件 public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。 (几乎…

    数据库 2023年6月16日
    084
  • MySQL连接时报错MySQL 8.0 ERROR 3118 (HY000): Access denied for user ‘root‘@‘localhost‘. Account is locked

    502 Bad Gateway nginx Original: https://www.cnblogs.com/diaoyulin/p/16272895.htmlAuthor: y…

    数据库 2023年6月6日
    0179
  • 力扣数据库题目182查找重复的电子邮箱

    力扣数据库题目182查找重复的电子邮箱 题目 编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。 示例: +—-+——&#82…

    数据库 2023年6月9日
    070
  • 三分钟小短文:一致性非锁定读与一致性锁定读

    台上三分钟,台下三小时,兄弟们,今天咱们花三分钟了解下数据库中的两种读(select)操作: 一致性非锁定读 和 一致性锁定读 一致性非锁定读 什么是一致的未锁定读取?在这里,我想…

    数据库 2023年5月24日
    066
  • Nginx 简介、安装、核心配置

    Nginx简介 背景介绍 Nginx(”engine x”)一个具有高性能的【HTTP】和【反向代理】的【WEB服务器】,同时也是一个【POP3/SMTP/…

    数据库 2023年6月6日
    092
  • [Mysql]Ubuntu如何安装Mysql+启用远程连接[完整版]

    嗯。以下是我踩了好几个小时的所有坑总结出来的血泪史。我希望我能帮你少踩几个坑。正常情况下,一步一步地,不会有任何问题。 [En] Yeah. The following is th…

    数据库 2023年5月24日
    089
  • Git的常见命令

    Git 一、git环境安装 1.初始化本地仓库: git init 2.将本地仓库跟远程仓库建立连接:git remote add name path ​ git clone pa…

    数据库 2023年6月16日
    077
  • 从 KeyStore 中获取 PublicKey 和 PrivateKey

    KeyStore(译:密钥存储库) 代表用于加密密钥和证书的存储设施。 KeyStore 管理不同类型的 entry(译:条目)。每种类型的 entry 都实现了 KeyStore…

    数据库 2023年6月14日
    097
  • 慢查询SQL排查

    转载请注明出处❤️ 作者:测试蔡坨坨 原文链接:caituotuo.top/c56bd0c5.html 你好,我是测试蔡坨坨。 在往期文章中,我们聊过数据库基础知识,可参考「数据库…

    数据库 2023年5月24日
    082
  • 从生命周期的角度看线程和进程之间的异同

    概述 进程与线程想必都不陌生,两者有诸多相同点,甚至可以这样说,线程就是”轻量级的进程”。而且两者基本的五个状态也几乎一样,但进程和线程在状态切换时的触发条…

    数据库 2023年6月11日
    073
  • MySQL45讲之count操作

    本文介绍 MyISAM 和 InnoDB 如何执行 count 操作,如果是一个需要使用 count 进行大量计数的场景,应该如何设计实现,以及不同 count 操作的效率。 My…

    数据库 2023年5月24日
    080
  • LeetCode 20. 有效的括号

    给定一个只包括 ‘(‘,’)’,'{‘,’}’,'[‘,’]&#8217…

    数据库 2023年6月11日
    086
  • mybatis-延迟加载

    本文主要介绍下mybatis的延迟加载,从原理上介绍下怎么使用、有什么好处能规避什么问题。延迟加载一般用于级联查询(级联查询可以将主表不能直接查询的数据使用自定义映射规则调用字表来…

    数据库 2023年6月16日
    060
  • 微信登录前端开发指南

    使用场景 微信公众号内嵌H5网页调用微信登录 在微信浏览器中的网页唤起微信登录界面 详情可以查阅微信登录官方文档 链接地址 功能思路 后台先在微信给开发者提供的测试账号平台上创建应…

    数据库 2023年6月11日
    068
  • java中重载(overload)与重写(override)的区别

    方法重载(overload): 方法重载就是在一个类中可以创建多个方法,它们具有相同的名字,但是具有不同的参数和不同的定义,调用方法时通过传递给它们的不同参数个数和参数类型来决定具…

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