我正在使用 Unity 开发汽车控制器,在应用旋转和转向动画时我遇到了车轮网格问题。这些动画是在适当的位置发生的,而不是在向前移动汽车对象时发生的。
当我尝试同时旋转车轮和转向时,车轮网格似乎无法同时处理这两个动画。当启用 AnimateWheelMeshes 方法时,转向动画似乎覆盖了两个前轮网格的旋转动画。
我正在为轮子网格和 WheelColliders 使用单独的游戏对象。当我尝试直接根据 WheelCollider 的旋转为车轮网格的旋转设置动画时,我希望前轮网格在转向时旋转。然而,这种方法导致与旋转动画冲突,似乎导致它被覆盖。
这是我的“carcontrolled”脚本的相关代码,带有注释以提供详细信息。似乎导致问题的方法是 AnimateWheelMeshes()。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class carcontrolled : MonoBehaviour
{
public GameObject frontLeftMesh;
public WheelCollider frontLeftCollider;
[Space(10)]
public GameObject frontRightMesh;
public WheelCollider frontRightCollider;
[Space(10)]
public GameObject rearLeftMesh;
public WheelCollider rearLeftCollider;
[Space(10)]
public GameObject rearRightMesh;
public WheelCollider rearRightCollider;
public float steeringAngle = 30f;
public float rotationSpeed = 2f;
public float acceleration = 5f;
public float maxSpeed = 30f;
public float sideMovementSpeed = 5f;
public float currentSpeed;
private void Update()
{
HandleInput();
// If you comment out the following method all wheels will spin in place.
// If you leave method uncommented the front wheel meshes will rotate left to right but not spin.
AnimateWheelMeshes();
}
private void HandleInput()
{
// Get input from the Vertical and Horizontal axes (e.g. W/S or Up/Down arrow keys and A/D or Left/Right arrow keys)
float verticalInput = Input.GetAxis("Vertical");
float horizontalInput = Input.GetAxis("Horizontal");
// If there is vertical input (i.e. accelerating or braking)
if (verticalInput != 0)
{
// Update the current speed based on the input and acceleration, taking the time since the last frame into account
currentSpeed += verticalInput * acceleration * Time.deltaTime;
// Clamp the current speed between -maxSpeed (reverse) and maxSpeed (forward)
currentSpeed = Mathf.Clamp(currentSpeed, -maxSpeed, maxSpeed);
}
// If there is no vertical input (i.e. not accelerating or braking)
else
{
// Gradually move the current speed towards 0 (stop) with the given acceleration
currentSpeed = Mathf.MoveTowards(currentSpeed, 0, acceleration * Time.deltaTime);
}
// Call the Steer method to handle the steering input and apply it to the car, using the current speed
Steer(horizontalInput, currentSpeed);
}
private void Steer(float steeringInput, float speed)
{
// Spins the wheels in place when vertical input axis is pressed
float rotationAngle = speed * Time.deltaTime * 360f;
Quaternion spinRotation = Quaternion.Euler(rotationAngle, 0, 0);
frontLeftMesh.transform.localRotation = frontLeftMesh.transform.localRotation * spinRotation;
frontRightMesh.transform.localRotation = frontRightMesh.transform.localRotation * spinRotation;
rearLeftMesh.transform.localRotation = rearLeftMesh.transform.localRotation * spinRotation;
rearRightMesh.transform.localRotation = rearRightMesh.transform.localRotation * spinRotation;
// Rotates colliders from left to right when horizontal input axis is pressed
float targetAngle = steeringAngle * steeringInput;
frontLeftCollider.steerAngle = Mathf.Lerp(frontLeftCollider.steerAngle, targetAngle, Time.deltaTime * rotationSpeed);
frontRightCollider.steerAngle = Mathf.Lerp(frontRightCollider.steerAngle, targetAngle, Time.deltaTime * rotationSpeed);
// Steers the car object from left to right when horizontal input axis is pressed
Vector3 sideMovement = transform.right * steeringInput * sideMovementSpeed * Time.deltaTime;
transform.position = Vector3.Lerp(transform.position, transform.position + sideMovement, Time.deltaTime);
}
void AnimateWheelMeshes()
{
// This method matches the mesh rotation with the rotation of the colliders. When this method is enabled it causes the issue.
Quaternion FLWRotation;
Vector3 FLWPosition;
frontLeftCollider.GetWorldPose(out FLWPosition, out FLWRotation);
frontLeftMesh.transform.position = FLWPosition;
// The following line when added causes the issue directly
frontLeftMesh.transform.rotation = FLWRotation;
Quaternion FRWRotation;
Vector3 FRWPosition;
frontRightCollider.GetWorldPose(out FRWPosition, out FRWRotation);
frontRightMesh.transform.position = FRWPosition;
// The following line when added causes the issue directly
frontRightMesh.transform.rotation = FRWRotation;
}
}