Unity 之 记录一个关于刚体穿透的问题
发布日期:2021-06-29 19:10:11
浏览次数:4
分类:技术文章
本文共 2559 字,大约阅读时间需要 8 分钟。
Unity 之 记录一个关于刚体穿透的问题
一,需求描述
需求:使得杆能够接住,依靠重力下落的球。
可是实现起来却和想象的不太一样,当杆移动速度快了就传过去了。 效果如下:二,遇到问题
看需求感觉还挺简单的。实现思路:几个球根据重力下落,一个“杆”跟随鼠标移动。步骤如下:
- 创建几个球并
Rigidbody
组件,并勾选useGravity
选项。 - 搭建场景如下图:
- 再创建一个Cube放大点(用来接住下落的球),也添加上
Rigidbody
组件并添加MouseMove
脚本:
using UnityEngine;public class MouseMove : MonoBehaviour{ void Update() { if (Input.GetMouseButton(0)) { // 根据鼠标位置 设置为 物体位置 Vector3 screenPos = Camera.main.WorldToScreenPoint(this.transform.position); Vector3 mousePos = Input.mousePosition; mousePos.z = screenPos.z; Vector3 worldPos = Camera.main.ScreenToWorldPoint(mousePos); // 控制物体移动 transform.position = worldPos; } }}
三,尝试解决
记得Rigidbody
组件,可以通过Collision Detection
属性来用于防止快速移动的对象穿过,这下面的检测方式都尝试了,也没有解决上述问题。
Unity 官方API:
Collision Detection | 用于防止快速移动的对象穿过其他对象而不检测碰撞。 |
---|---|
Discrete | 对场景中的所有其他碰撞体使用离散碰撞检测。其他碰撞体在测试碰撞时会使用离散碰撞检测。用于正常碰撞(这是默认值)。 |
Continuous | 对动态碰撞体(具有刚体)使用离散碰撞检测,并对静态碰撞体(没有刚体)使用基于扫掠的连续碰撞检测。设置为__连续动态 (Continuous Dynamic)__ 的刚体将在测试与该刚体的碰撞时使用连续碰撞检测。其他刚体将使用离散碰撞检测。用于__连续动态 (Continuous Dynamic)__ 检测需要碰撞的对象。(此属性对物理性能有很大影响,如果没有快速对象的碰撞问题,请将其保留为 Discrete 设置) |
Continuous Dynamic | 对设置为__连续 (Continuous)__ 和__连续动态 (Continuous Dynamic)__ 碰撞的游戏对象使用基于扫掠的连续碰撞检测。还将对静态碰撞体(没有刚体)使用连续碰撞检测。对于所有其他碰撞体,使用离散碰撞检测。用于快速移动的对象。 |
Continuous Speculative | 对刚体和碰撞体使用推测性连续碰撞检测。这也是可以设置运动物体的唯一 CCD 模式。该方法通常比基于扫掠的连续碰撞检测的成本更低。 |
测试小结
- 测试时也尝试了快速移动时的检测逻辑,在速度不是特别快的情况下,修改
Collsion Detection
选项调成Continues Dynamic
是可以满足条件的,但是超过一定速度还是能穿透过去。 - 记得在尝试过程中还看到过:调整ProjectSetting -> Time-> FixedTimestep的检测间隔进一步缩小。(例如0.003;提高物理系统的更新速度)【测试也没成功】
- 若是发射子弹这种逻辑,可以使用射线检测的方式,在子弹发射的时候发射射线检测到的碰撞点进行逻辑判断处理。
四,实现需求
最后使用移动刚体的方式,来移动“杆”,测试结果如下:
修改后的代码:using UnityEngine;public class MouseMove : MonoBehaviour{ private Rigidbody _rigidbody; void Start() { _rigidbody = transform.GetComponent(); // 取消重力 _rigidbody.useGravity = false; // 设置为不再受物理引擎的影响 _rigidbody.isKinematic = true; } void Update() { if (Input.GetMouseButton(0)) { // 根据鼠标位置 设置为 物体位置 Vector3 screenPos = Camera.main.WorldToScreenPoint(this.transform.position); Vector3 mousePos = Input.mousePosition; mousePos.z = screenPos.z; Vector3 worldPos = Camera.main.ScreenToWorldPoint(mousePos); // 控制物体移动 //transform.position = worldPos; // 修改为刚体控制移动 --> 则不会被穿透了 _rigidbody.MovePosition(worldPos); } }}
若还有不明白的地方,可以评论咨询,或者点击链接查看示例源码:
转载地址:https://czhenya.blog.csdn.net/article/details/113858882 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月09日 00时40分54秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Hive 分区--静态分区、动态分区
2019-04-30
Hive DML、SerDe
2019-04-30
Hive 函数
2019-04-30
Hive 练习一 单词统计、建表复合数据类型struct
2019-04-30
Hive 参数
2019-04-30
Hive 分桶
2019-04-30
Hive运行方式&GUI接口
2019-04-30
Hive 权限管理
2019-04-30
Hive Lateral View & 视图 & 索引
2019-04-30
org.apache.dubbo.remoting.TimeoutException
2019-04-30
CentOS7使用NTP搭建时间同步服务器
2019-04-30
JavaScript代码技巧
2019-04-30
对标 Spring Boot & Cloud ,轻量框架 Solon 1.5.8 发布
2019-04-30
老生常谈的GC垃圾回收,让我来“重新定义”,不信你还不明白
2019-04-30
配置中心(Nacos)
2019-04-30
分布式网关(GateWay)
2019-04-30
网关配置全局跨域请求(CorsWebFilter)
2019-04-30
分布式缓存(SpringCache)
2019-04-30