c# - Unity RigidBody Physics:不重叠层时发生碰撞
问题描述
Unity 是否有类似 CollideWhenRigidBodyLeavesLayer 方法的东西?原因如下:
我的 npc 有三种运动类型:步行、游泳和飞行
他们使用刚体进行运动,并且对于行走的角色非常有效。
它也适用于飞行的角色。通过调用 Physics.IgnoreLayerCollision(FlyingCharacterLayer, WaterLayer) 飞行角色现在能够飞越水面。
我的问题是,我怎样才能让我的游泳生物保持与水层重叠?
我打开了 Physics.IgnoreLayerCollision(SwimmingCharacterLayer, WaterLayer) 所以现在游泳的角色可以与水重叠。
但是我如何测试我的海洋生物正在离开水并在这里产生碰撞,所以他转身继续游泳而不是进化成一条会走路的鱼......
我的水平(以及水)是动态生成的,因此为碰撞测试添加周边障碍不是一个很好的选择。
此外,“地面”图形/图层存在于水层下,因此我认为没有一种测试与地面碰撞的好方法,因为我的鱼同时与地面和水重叠。
我希望我缺少一些基本的东西:)
谢谢!
更新:我可以检查我的游泳角色是否不再与 Physics.CheckSphere 重叠
但我不知道从那里做什么。如果我尝试将他转 180 度,他会翻转每一帧,有时会回到水中,有时不会……
if(Physics.CheckSphere(transform.position, 0.25f, LayerMask.NameToLayer("Water")) == false)
{
// Now I know that my fish is out of the water
// but I can not figure out how to turn him around
}
解决方案
我并不为此感到自豪,但在这里摆弄之后就是我想出的。
它似乎把鱼留在了池塘里,但弹跳并不漂亮。
它也完全违反了“不要对刚体变换大惊小怪”的规则......但是因为物理系统无论如何都不会与我一起工作......
enum CheckDirection { AHEAD, LEFT, RIGHT };
bool CheckAheadIsWater(CheckDirection dir = CheckDirection.AHEAD)
{
if(dir == CheckDirection.AHEAD)
return Physics.CheckSphere(transform.position + transform.forward * 1.5f, 0.5f, LayerMask.GetMask(Settings.LayerWater));
if(dir == CheckDirection.RIGHT)
return Physics.CheckSphere(transform.position + forward + transform.right * 2f, 0.5f, LayerMask.GetMask(Settings.LayerWater));
if(dir == CheckDirection.LEFT)
return Physics.CheckSphere(transform.position + transform.forward - transform.right * 2f, 0.5f, LayerMask.GetMask(Settings.LayerWater));
throw new System.Exception("No Check Existes For " + dir);
}
void Update()
{
if (!CheckAheadIsWater(CheckDirection.RIGHT))
{
print("about to leave water RIGHT");
//turn left 45 degrees
transform.rotation = Quaternion.LookRotation(transform.forward + transform.right * 0.5f);
}
if (!CheckAheadIsWater(CheckDirection.LEFT))
{
print("about to leave water LEFT");
//turn right 45 degrees
transform.rotation = Quaternion.LookRotation(transform.forward - transform.right * 0.5f);
}
if (!CheckAheadIsWater())
{
print("about to leave water AHEAD");
//bounce back 1 unit
physicalBody.MovePosition(transform.position - transform.forward);
//swim the opposite direction
transform.rotation = Quaternion.LookRotation(-transform.forward);
}
}
推荐阅读
- javascript - react js中的函数和类
- javascript - 如何检查对象内的数组是否为空
- python - BeautifulSoup:在特定跨度之后提取文本中的数据
- javascript - Babel preset-env 未加载节点目标的顶级等待语法
- watson-discovery - 培训中的近期查询
- android - 如何检查将来是否可见视图?
- bash - Ansible 从 bash 读取变量
- php - 如何在 laravel 6 中进行分页?上面的异常{调用未定义的方法 App\Clothes::links()}
- jboss-arquillian - Arquillian/Shrinkwrap 社区论坛搬家了吗?
- c++ - 为什么在此处覆盖字符串文字(C++)?