c# - Unity 3D如何旋转对象以使其基于地平面正确定向?
问题描述
我正在使用一个名为 Dreamteck Splines 的资产来创建一条路径,我想做的是让它在我旋转样条曲线时游戏对象在这种情况下粉红色立方体也会旋转,因此它在路径上是否正确定向它像过山车一样颠倒或侧向。出于某种原因,我只能在立方体停止旋转以使其与路径对齐之前将路径旋转到大约 90 度。 GIF
if (Input.GetKey(KeyCode.W))
{
vehicle.transform.Translate(0, 0, speed * Time.deltaTime);
}
if (Physics.Raycast(vehicle.transform.position, Vector3.down, out hit, 100))
{
Vector3 surfaceNormal = hit.normal; // Assign the normal of the surface to surfaceNormal
Vector3 forwardRelativeToSurfaceNormal = Vector3.Cross(vehicle.transform.InverseTransformDirection(vehicle.transform.right), surfaceNormal);
Quaternion targetRotation = Quaternion.LookRotation(forwardRelativeToSurfaceNormal, surfaceNormal); //check For target Rotation.
vehicle.transform.rotation = Quaternion.Lerp(vehicle.transform.rotation, targetRotation, Time.deltaTime * 20); //Rotate Character accordingly.
}
解决方案
我发现这可以实现我想要实现的目标:
void Update()
{
/*Here we get user input to calculate the speed the ship will get*/
if (Input.GetKey(KeyCode.W))
{
/*Increase our current speed only if it is not greater than fwd_max_speed*/
current_speed += (current_speed >= fwd_max_speed) ? 0f : fwd_accel * Time.deltaTime;
}
else
{
if (current_speed > 0)
{
/*The ship will slow down by itself if we dont accelerate*/
current_speed -= brake_speed * Time.deltaTime;
}
else
{
current_speed = 0f;
}
}
/*We get the user input and modifiy the direction the ship will face towards*/
yaw += turn_speed * Time.deltaTime * Input.GetAxis("Horizontal");
/*We want to save our current transform.up vector so we can smoothly change it later*/
prev_up = transform.up;
/*Now we set all angles to zero except for the Y which corresponds to the Yaw*/
transform.rotation = Quaternion.Euler(0, yaw, 0);
RaycastHit hit;
if (Physics.Raycast(transform.position, -prev_up, out hit))
{
Debug.DrawLine(transform.position, hit.point);
/*Here are the meat and potatoes: first we calculate the new up vector for the ship using lerp so that it is smoothed*/
Vector3 desired_up = Vector3.Lerp(prev_up, hit.normal, Time.deltaTime * pitch_smooth);
/*Then we get the angle that we have to rotate in quaternion format*/
Quaternion tilt = Quaternion.FromToRotation(transform.up, desired_up);
/*Now we apply it to the ship with the quaternion product property*/
transform.rotation = tilt * transform.rotation;
/*Smoothly adjust our height*/
smooth_y = Mathf.Lerp(smooth_y, hover_height - hit.distance, Time.deltaTime * height_smooth);
transform.localPosition += prev_up * smooth_y;
}
/*Finally we move the ship forward according to the speed we calculated before*/
transform.position += transform.forward * (current_speed * Time.deltaTime);
}
推荐阅读
- javascript - 使用 Sheets API 和 GAS 删除无效的命名范围
- javascript - 如何隐藏一个div下面的所有div元素?
- windows - 无法 RDP 进入 Windows?
- typescript - Nuxt 自定义插件导出未定义
- kubernetes - Google 的 Cloud Run 与传统的 Kubernetes 集群有何不同?
- java - 如何序列化 BCMcEliecePublicKey?
- python - 如何将 Counter 的结果放入两个列表中?
- android - findViewById() 从自定义视图返回 null
- excel - 复制粘贴宏的工作方式因活动工作表而异
- python - 从 BeautifulSoup Python 获取 CDATA