我将使用什么公式将速度与 Unity 的旋转相关联?
What formula would I use to relate velocity to rotation I Unity?
我正在 Unity 中尝试为基于物理的箭头创建脚本。
我的弧线正常,但在整个飞行过程中它仍然笔直向上。
我正在尝试使用 Quaternion.LookRotation
来根据速度 (R = 0 at V = Vinitial, R = 90 at V = 0, and R = 180 at V = -Vinitial)
更改它的旋转,但我一直无法弄清楚我将使用什么公式。
任何帮助将不胜感激。
编辑
在回复的帮助下,我能够让它按预期工作。万一有人偶然发现这个问题寻求帮助,我的最终代码如下所示:
private void Update()
{
if (ForceSet)
{
ForceSet = false;
initialVelocity = rb.velocity;
EndAngleOffset = .33f * rb.velocity.y;
}
if (stuckTarget == null)
{
Vector3 Forward;
Vector3 Upward;
if (rb.velocity.y > 0)
{
Forward = new Vector3(rb.velocity.x, -((-initialVelocity.y + rb.velocity.y - EndAngleOffset) * (-initialVelocity.y + rb.velocity.y - EndAngleOffset)), rb.velocity.z);
Upward = new Vector3(0, 1, 0);
}
else
{
Forward = new Vector3(rb.velocity.x, ((initialVelocity.y + rb.velocity.y + EndAngleOffset) * (initialVelocity.y + rb.velocity.y + EndAngleOffset)), rb.velocity.z);
Upward = new Vector3(0, -1, 0);
}
rb.rotation = Quaternion.LookRotation(Forward, Upward);
}
(当向 'Arrow' 施加发射力时,ForceSet 设置为 true)
如果您有权访问箭头 Rigidbody
组件,则可以访问它的 velocity
属性 并将其 rotation
设置为等于其 velocity
.
我建议在对 Rigidbody
的转换进行修改时使用 Rigidbody
方法。这可确保使用 Unity 的物理系统正确更新值。
using UnityEngine;
public class ArrowBehaviour : MonoBehaviour
{
private Rigidbody rigidbody;
private void Awake()
{
rigidbody = GetComponent<Rigidbody>();
}
private void Update()
{
rigidbody.rotation = Quaternion.LookRotation(rigidbody.velocity, Vector3.up);
}
}
根据具体情况,您可能希望将 Update
更改为 FixedUpdate
。
编辑:
上面的代码中有一个 bug 我修复了;这就是你在凌晨 2 点写它时得到的结果。我会再试一次,看看是否适合你。
在理想情况下,您会 pre-compute 箭头的路径,以便您可以对所需的箭头执行任何程序动画。
您也可以计算一个 X 旋转来代替使用,这将伪造效果。
using UnityEngine;
public class ArrowBehaviour : MonoBehaviour
{
[SerializeField] private float lookMagnitude = 45.0f;
[SerializeField] private float velocitySensitivity;
private Rigidbody rigidbody;
private void Awake()
{
rigidbody = GetComponent<Rigidbody>();
}
private void Update()
{
// Determine how much we want to fake the rotation by.
var lookStrength = Mathf.InverseLerp(-velocitySensitivity, velocitySensitivity, rigidbody.velocity)
var targetEulerAngles = new Vector3(
Mathf.Lerp(-lookMagnitude, lookMagnitude, lookStrength),
transform.localEulerAngles.y,
transform.localEulerAngles.z
);
// Rotate the transform
transform.localEulerAngles = targetEulerAngles;
// Alternatively, interpolate to the target angle.
/* transform.localEulerAngles = Vector3.Lerp(
* transform.localEulerAngles,
* targetEulerAngles,
* Time.deltaTime * rotationSpeed
* );
*/
}
}
获取变换旋转并将其设置为等于Quaternion.LookRotation(velocity)
应该没问题
我正在 Unity 中尝试为基于物理的箭头创建脚本。
我的弧线正常,但在整个飞行过程中它仍然笔直向上。
我正在尝试使用 Quaternion.LookRotation
来根据速度 (R = 0 at V = Vinitial, R = 90 at V = 0, and R = 180 at V = -Vinitial)
更改它的旋转,但我一直无法弄清楚我将使用什么公式。
任何帮助将不胜感激。
编辑
在回复的帮助下,我能够让它按预期工作。万一有人偶然发现这个问题寻求帮助,我的最终代码如下所示:
private void Update()
{
if (ForceSet)
{
ForceSet = false;
initialVelocity = rb.velocity;
EndAngleOffset = .33f * rb.velocity.y;
}
if (stuckTarget == null)
{
Vector3 Forward;
Vector3 Upward;
if (rb.velocity.y > 0)
{
Forward = new Vector3(rb.velocity.x, -((-initialVelocity.y + rb.velocity.y - EndAngleOffset) * (-initialVelocity.y + rb.velocity.y - EndAngleOffset)), rb.velocity.z);
Upward = new Vector3(0, 1, 0);
}
else
{
Forward = new Vector3(rb.velocity.x, ((initialVelocity.y + rb.velocity.y + EndAngleOffset) * (initialVelocity.y + rb.velocity.y + EndAngleOffset)), rb.velocity.z);
Upward = new Vector3(0, -1, 0);
}
rb.rotation = Quaternion.LookRotation(Forward, Upward);
}
(当向 'Arrow' 施加发射力时,ForceSet 设置为 true)
如果您有权访问箭头 Rigidbody
组件,则可以访问它的 velocity
属性 并将其 rotation
设置为等于其 velocity
.
我建议在对 Rigidbody
的转换进行修改时使用 Rigidbody
方法。这可确保使用 Unity 的物理系统正确更新值。
using UnityEngine;
public class ArrowBehaviour : MonoBehaviour
{
private Rigidbody rigidbody;
private void Awake()
{
rigidbody = GetComponent<Rigidbody>();
}
private void Update()
{
rigidbody.rotation = Quaternion.LookRotation(rigidbody.velocity, Vector3.up);
}
}
根据具体情况,您可能希望将 Update
更改为 FixedUpdate
。
编辑:
上面的代码中有一个 bug 我修复了;这就是你在凌晨 2 点写它时得到的结果。我会再试一次,看看是否适合你。
在理想情况下,您会 pre-compute 箭头的路径,以便您可以对所需的箭头执行任何程序动画。
您也可以计算一个 X 旋转来代替使用,这将伪造效果。
using UnityEngine;
public class ArrowBehaviour : MonoBehaviour
{
[SerializeField] private float lookMagnitude = 45.0f;
[SerializeField] private float velocitySensitivity;
private Rigidbody rigidbody;
private void Awake()
{
rigidbody = GetComponent<Rigidbody>();
}
private void Update()
{
// Determine how much we want to fake the rotation by.
var lookStrength = Mathf.InverseLerp(-velocitySensitivity, velocitySensitivity, rigidbody.velocity)
var targetEulerAngles = new Vector3(
Mathf.Lerp(-lookMagnitude, lookMagnitude, lookStrength),
transform.localEulerAngles.y,
transform.localEulerAngles.z
);
// Rotate the transform
transform.localEulerAngles = targetEulerAngles;
// Alternatively, interpolate to the target angle.
/* transform.localEulerAngles = Vector3.Lerp(
* transform.localEulerAngles,
* targetEulerAngles,
* Time.deltaTime * rotationSpeed
* );
*/
}
}
获取变换旋转并将其设置为等于Quaternion.LookRotation(velocity)