c# - Quaternion.RotateTowards 期间圆柱体对齐到位
问题描述
我想要做的是在场景的中心有一个支柱,我认为正在发生的是四元数。RotateTowards 接收的起始/初始四元数与导致它捕捉/传送到不同的动作的动作不同然后开始移动到下一个位置。我想这可能是因为我误解了四元数是如何统一处理的,所以我试着把它标准化,但我似乎无法在瞬移上得到任何改变。
我们的目标是将这个脚本附加到一个简单的 3D 圆柱体上并让它基本上摆动,在那里会有一个玩家在它上面试图停留在上面。但是我似乎无法弄清楚它为什么会传送并希望有第二双眼睛。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlatformWobble : MonoBehaviour
{
public float timeDelay = 0;
public float rRange = 0.5f;
public float maxRotation = 20.0f;
public float rotRate = 0.05f;
private bool wobble = false;
private Vector3 randomRotation;
private Quaternion rotation;
private Quaternion destination;
private float x, y, z;
private bool inPlace;
private void Start()
{
randomRotation = new Vector3();
inPlace = true;
}
// Update is called once per frame
void FixedUpdate()
{
if (inPlace)
{
destination = RotateRandomly();
inPlace = false;
}
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, destination, rotRate * Time.deltaTime);
if (transform.localRotation == destination)
{
inPlace = true;
}
}
//This will grab the rotation of the object and move it randomly, but won't exceed maxRotation;
Quaternion RotateRandomly()
{
randomRotation = new Vector3(Random.Range(-rRange, rRange), Random.Range(-rRange, rRange), Random.Range(-rRange, rRange));
rotation = transform.localRotation;
x = rotation.x + randomRotation.x;
if(x >= maxRotation && x <= 360 - maxRotation) { x = rotation.x; }
y = rotation.y + randomRotation.y;
if (y >= maxRotation && y <= 360 - maxRotation) { y = rotation.y; }
z = rotation.z + randomRotation.z;
if (z >= maxRotation && z <= 360-maxRotation) { z = rotation.z; }
return new Quaternion(x, y, z, transform.localRotation.w);
}
}
解决方案
FixedUpdate
不会在每个渲染帧上调用,仅在物理帧上调用。您需要一种方法来告诉 Unity 让每个帧都显示旋转变化,而不是仅在物理帧刚刚运行时更新渲染。
这就是Rigidbody.MoveRotation
目的。缓存对 的引用Rigidbody
,计算它应该具有的新全局旋转,然后调用MoveRotation
:
private Rigidbody rb;
private void Start()
{
randomRotation = new Vector3();
inPlace = true;
rb = GetComponent<Rigidbody>();
}
// ...
// Update is called once per frame
void FixedUpdate()
{
if (inPlace)
{
destination = RotateRandomly();
inPlace = false;
}
Quaternion newLocalRot = Quaternion.RotateTowards(transform.localRotation,
destination, rotRate * Time.deltaTime);
Quaternion newGlobalRot = transform.parent.rotation * newLocalRot;
rb.MoveRotation(newGlobalRot);
if (transform.localRotation == destination)
{
inPlace = true;
}
}
推荐阅读
- excel - IF/AND + INDEX/MATCH 公式可以根据多个条件提取值吗?
- null - simplefunge - NilClass 错误,即使堆栈顶部不为空
- flutter - 如何在 Flutter 中模糊 Container 或 Any 小部件
- python - 在重新运行测试时防止过早的会话夹具拆卸
- excel - 在 Excel 中通过 VBA 打开排序对话框
- java - 如果有初始化的子集合,则使用 PagingAndSortingRepository.save 保存实体会产生 @PostUpdate/@PostCreate 事件
- sql - 如何将一个记录列更新为真,其他全部为假
- logstash - Logstash :过滤日志中的列值
- angularjs - 从 mongodb 计算每个不同的值,然后渲染到 amcharts
- java - 在服务器中启动应用程序时 printStackTrace() 日志的位置