Unity移动端替换Input.GetAxis实现触控车辆转向功能
Unity 手机端车辆触摸转向控制实现方案
原有PC端控制逻辑
最初PC端通过横轴输入控制车轮转向的代码如下:
float steer = Input.GetAxis("Horizontal"); float finalangel = steer * 45f; wheelcoll[0].steerAngle = finalangel;
手机端适配需求
- 用户触摸按住屏幕时,车辆持续向左转向并保持转向状态
- 手指离开屏幕后,车辆自动回正到初始朝向
- 转向、回正过程方向准确,无逻辑冲突
原有代码存在的问题
- 触摸按下、抬起事件触发了完全相同的逻辑,无法区分按住和松开状态
- 大量使用
Invoke延迟修改变量状态,导致转向逻辑被频繁打断,无法实现按住持续转向的效果 - 旋转回正逻辑和位置逻辑绑定了无意义的坐标判断,状态切换存在冲突
原有尝试代码如下:
[SerializeField] Rigidbody rb; public Vector3 targetpostion; public int Speed; public bool FirstLaneBlueCar; public bool BlueCar; public Vector2 Xpos; public float rotatlerptime; bool rottrue; void Start() { rottrue = false; BlueCar = false; } void Update() { if (Input.GetMouseButtonDown(0)) { BlueCar = true; rottrue = true; LeftButtonPressed(); }else if (Input.GetMouseButtonUp(0)) { BlueCar = true; rottrue = true; LeftButtonPressed(); } if (!rottrue) { if (transform.position.x <= 4f) { Debug.Log(">-.5"); transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime); } if (transform.position.x >= 3f) { Debug.Log(">.5f"); transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime); } } } private void FixedUpdate() { transform.Translate(targetpostion, Space.World); if (BlueCar) { if (FirstLaneBlueCar) { if (rottrue) { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, -60f, 0), rotatlerptime * Time.deltaTime); Invoke("rot2", .1f); } Invoke("left", .1f); } else { if (rottrue) { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 60f, 0), rotatlerptime * Time.deltaTime); Invoke("rot2", .1f); } Invoke("right", .1f); } } } public void rot2() { rottrue = false; } void left() { transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.y, transform.position.y, transform.position.z), .08f); } void right() { transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.x, transform.position.y, transform.position.z), .08f); } public void LeftButtonPressed() { if (FirstLaneBlueCar) { FirstLaneBlueCar = false; } else { FirstLaneBlueCar = true; } }
参考示意图

可直接使用的实现方案
核心逻辑是将转向状态直接和触摸按住状态强绑定,去掉冗余状态变量和延迟调用,保证转向过程连续:
using UnityEngine; public class TouchCarSteer : MonoBehaviour { [Header("转向参数配置")] public float maxSteerAngle = 45f; // 最大转向角度 public float steerSmoothSpeed = 6f; // 转向/回正平滑速度 public float forwardSpeed = 12f; // 车辆前进速度 [Header("组件引用")] public WheelCollider steerWheel; // 用WheelCollider方案时赋值前轮碰撞器,不用可留空 private bool isPressing = false; private float currentSteer = 0f; void Update() { // 单指触摸自动映射为GetMouseButton状态,无需额外写Touch判断 isPressing = Input.GetMouseButton(0); // 按住时目标角度为最大左转角,松开时目标角度为0(回正) float targetSteer = isPressing ? -maxSteerAngle : 0f; // 逐帧平滑插值转向角,避免角度跳变 currentSteer = Mathf.Lerp(currentSteer, targetSteer, steerSmoothSpeed * Time.deltaTime); // 适配两种控制方案 if (steerWheel != null) { steerWheel.steerAngle = currentSteer; } else { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, currentSteer, 0), steerSmoothSpeed * Time.deltaTime); } } private void FixedUpdate() { // 车辆前进逻辑,可根据自己的项目需求修改 if (TryGetComponent(out Rigidbody rb)) { rb.MovePosition(transform.position + transform.forward * forwardSpeed * Time.fixedDeltaTime); } } }
参数调整说明
- 需要切换转向方向时,把
targetSteer赋值的负号去掉即可实现按住右转 - 调大
steerSmoothSpeed会让转向/回正速度更快,调小则转向更柔和 - 如果需要变道逻辑,直接在触摸状态判断里加位置插值即可,不要用
Invoke延迟打断转向状态
内容的提问来源于stack exchange,提问作者keyvan
相关产品推荐
相关产品推荐

