unity3d - unity:计算刚体的角速度以始终面向特定方向
问题描述
我正在尝试制作像 Amnesia 中的拾取对象机制。计算所需的刚体速度很容易,因此被握住的物体保持在相机前面,但我的问题是当我握住它时物体根本不旋转。我宁愿让它总是朝着相机旋转。这可以通过简单地将对象添加到玩家的相机来轻松实现,但是......
我追求的行为如下:如果我拿起的瓶子站在桌子上,瓶子的脖子朝向天花板,我希望看到这个瓶子在我拿着它时它的脖子总是朝向天花板。但是如果这个瓶子与某物碰撞,它应该表现得就像它实际上撞到了某物,所以它应该旋转一些小量,但它应该始终尝试返回其“原始”旋转(在这种情况下,颈部朝向天花板)。
我认为我需要为此计算角速度,并且可能需要一些 lerp 来恢复原始旋转,但我不知道如何正确地做到这一点。
我认为我需要做的第一件事是存储玩家捡起物体时的初始方向:
Vector3 targetDirection = playerCamera.transform.position - transform.position;
脚本在持有的对象上,所以“变换”指的是它。在 FixedUpdate() 中,我可能需要进行一些插值,以便角速度始终尝试将对象旋转到原始旋转:
rigidbody.angularVelocity = Vector3.Lerp(rigidbody.angularVelocity, targetAngularVelocity, lerpSpeed * Time.fixedDeltaTime);
我不知道如何计算 targetAngularVelocity,因为毕竟我希望被持有的物体能够顺利返回到原始旋转。我什至不确定这是否是做这件事的正确方法,也许我应该做点别的事情,而不是计算正确旋转物体所需的角速度。我尝试将 localRotation 插值到原始的局部旋转,但这并不允许被握住的物体碰到东西(当时的运动非常紧张)。有任何想法吗?
解决方案
你需要一个稳定器。一个脚本,它将向对象添加扭矩/角速度,其角度与目标角度不同。说,你有两个变量:targetDirection
和currentDirection
aka transform.forward
。然后你在固定更新中写这样的东西:
var rotation = Quaternion.FromToRotation(currentDirection, targetDirection).eulerAngles * sensitivity;
rigidbody.angularVelocity = rotation;
我建议将灵敏度设置为 0.05 左右,如果物体稳定得太慢,请增加它。可能我混淆了顺序,所以你应该把减号放在某个地方,但方法本身是适用的。
推荐阅读
- .net - Visual Studio 2017 不能针对 .Net 标准 2.0,但 Visual Studio 2019 可以吗?
- bixby - Bixby:无法将 payInfo.currency 强制转换为字符串
- javascript - 加入、分组和计算两个 javascript 对象
- c++ - GDI+ 和多线程
- firebase - 'auth/invalid-api-key' 让 Admin SDK 发现服务帐户时
- angular - 监听指令内的自定义组件事件
- php - 如何从数组中找到特定的id
- r - 如何在程序上计算大量向量之间的角度?
- c++ - set_terminate() 上的 Lambda 函数
- angular - 如何在 Angular 中覆盖 HttpErrorResponse