Unity中键鼠控制Player Sprite移动时闪烁问题求助
2D俯视角射击控制器键鼠+手柄共存时移动闪烁问题
我正在开发一款2D俯视角射击控制器,多数情况下运行正常,但同时连接键鼠与手柄时,使用键鼠控制Player Sprite移动偶尔会出现闪烁现象,仅使用手柄时无此问题。
移动脚本代码
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; public class PlayerMovement : MonoBehaviour { [SerializeField] float playerSpeed = 5f; [SerializeField] float controllerDeadzone = 0.1f; [SerializeField] float gamepadRotationSmoothing = 1000f; [SerializeField] bool isGamepad; Rigidbody2D _rigidbody2D; PlayerInput playerInput; Controllers controllers; Vector2 movement; Vector2 aim; private void Awake() { _rigidbody2D = GetComponent<Rigidbody2D>(); playerInput = GetComponent<PlayerInput>(); controllers = new Controllers(); } void OnEnable() { controllers.Enable(); } void OnDisable() { controllers.Disable(); } void FixedUpdate() { HandleInput(); HandleMovement(); HandleRotation(); } private void HandleInput() { movement = controllers.Controls.Movement.ReadValue<Vector2>(); aim = controllers.Controls.Aim.ReadValue<Vector2>(); } private void HandleMovement() { Vector2 move = new Vector2(movement.x, movement.y); _rigidbody2D.velocity = move * playerSpeed * Time.deltaTime; } private void HandleRotation() { Vector2 playerDirection = new Vector2(aim.x, aim.y); float rotationDegree = Mathf.Atan2(playerDirection.y, playerDirection.x) * Mathf.Rad2Deg - 90f; if (isGamepad) { if (Mathf.Abs(aim.x) > controllerDeadzone || Mathf.Abs(aim.y) > controllerDeadzone) { if (playerDirection.sqrMagnitude > 0.0f) { Quaternion newRotation = Quaternion.Euler(0, 0, rotationDegree); transform.rotation = Quaternion.RotateTowards(transform.rotation, newRotation, gamepadRotationSmoothing * Time.deltaTime); } } } else { Vector3 mouseWorldPosition = Camera.main.ScreenToWorldPoint(aim); Vector3 targetDirection = mouseWorldPosition - transform.position; float angle = Mathf.Atan2(targetDirection.y, targetDirection.x) * Mathf.Rad2Deg - 90f; transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle)); } } public void OnDeviceChange(PlayerInput pi) { isGamepad = pi.currentControlScheme.Equals("Gamepad") ? true : false; } }
问题排查与修复方案
1. 修复输入冲突:过滤手柄静默输入
当同时连接键鼠和手柄时,手柄摇杆即使未操作也可能返回微小非零值,混合键鼠输入导致移动抖动。修改HandleInput方法,根据当前控制方案过滤无效输入:
private void HandleInput() { if (isGamepad) { movement = controllers.Controls.Movement.ReadValue<Vector2>(); // 死区过滤手柄微小输入 if (movement.magnitude < controllerDeadzone) movement = Vector2.zero; } else { movement = controllers.Controls.Movement.ReadValue<Vector2>(); } aim = controllers.Controls.Aim.ReadValue<Vector2>(); }
2. 同步输入读取与帧更新逻辑
InputSystem的输入更新频率与FixedUpdate不同步,易引发输入跳变。将输入读取移到Update中,物理更新保留在FixedUpdate:
void Update() { HandleInput(); } void FixedUpdate() { HandleMovement(); HandleRotation(); }
3. 修正速度计算错误
Rigidbody2D的velocity单位是单位/秒,无需乘以Time.deltaTime,错误缩放会导致速度异常抖动:
private void HandleMovement() { _rigidbody2D.velocity = movement * playerSpeed; }
4. 实时检测输入设备,避免切换延迟
OnDeviceChange可能存在触发延迟,在HandleInput中实时判断当前活跃输入设备:
private void HandleInput() { // 实时检测是否使用手柄 isGamepad = Gamepad.current != null && Gamepad.current.isActive; movement = controllers.Controls.Movement.ReadValue<Vector2>(); // 仅对手柄输入应用死区 if (isGamepad && movement.magnitude < controllerDeadzone) movement = Vector2.zero; aim = controllers.Controls.Aim.ReadValue<Vector2>(); }
内容的提问来源于stack exchange,提问作者Reza Rahem
相关产品推荐
相关产品推荐

