使用Unity InputSystem时,如何通过C#事件区分不同玩家?
解决Unity本地多人游戏中C#事件区分玩家的问题
核心思路是让每个玩家实例的脚本单独订阅自身的输入事件,而非全局统一监听,这样每个事件触发时仅关联对应玩家的逻辑,自然能区分不同设备的输入。
方法1:使用Input System生成的C#动作类
首先确保你的Input Action Asset已生成对应C#类(右键Input Action Asset → Generate C# Class),然后在玩家脚本中绑定自身的输入事件:
using UnityEngine; using UnityEngine.InputSystem; public class PlayerController : MonoBehaviour { private PlayerInput _playerInput; // 替换成你生成的Input Action类名称 private PlayerInputActions _inputActions; void Awake() { // 获取当前玩家的PlayerInput组件 _playerInput = GetComponent<PlayerInput>(); // 初始化输入动作实例 _inputActions = new PlayerInputActions(); // 启用玩家动作映射(替换成你自己的映射名称) _inputActions.Player.Enable(); // 订阅具体动作的C#事件,这里以Jump和Move为例 _inputActions.Player.Jump.performed += OnJumpPerformed; _inputActions.Player.Move.performed += OnMovePerformed; } void OnDestroy() { // 必须取消订阅,避免内存泄漏 _inputActions.Player.Jump.performed -= OnJumpPerformed; _inputActions.Player.Move.performed -= OnMovePerformed; _inputActions.Dispose(); } private void OnJumpPerformed(InputAction.CallbackContext context) { // 通过playerIndex区分玩家,或直接操作当前脚本所属GameObject Debug.Log($"玩家 {_playerInput.playerIndex} 触发跳跃"); } private void OnMovePerformed(InputAction.CallbackContext context) { Vector2 moveInput = context.ReadValue<Vector2>(); Debug.Log($"玩家 {_playerInput.playerIndex} 的移动输入:{moveInput}"); } }
方法2:使用PlayerInput内置的onActionTriggered事件
如果不想生成C#动作类,可直接订阅PlayerInput组件自带的onActionTriggered事件,在回调中判断动作类型:
using UnityEngine; using UnityEngine.InputSystem; public class PlayerController : MonoBehaviour { private PlayerInput _playerInput; void Awake() { _playerInput = GetComponent<PlayerInput>(); // 订阅当前玩家的输入触发事件 _playerInput.onActionTriggered += OnPlayerActionTriggered; } void OnDestroy() { _playerInput.onActionTriggered -= OnPlayerActionTriggered; } private void OnPlayerActionTriggered(InputAction.CallbackContext context) { // 根据动作名称区分不同输入 switch (context.action.name) { case "Jump": Debug.Log($"玩家 {_playerInput.playerIndex} 跳跃"); break; case "Move": Vector2 moveInput = context.ReadValue<Vector2>(); Debug.Log($"玩家 {_playerInput.playerIndex} 移动:{moveInput}"); break; } } }
关键注意点
- 每个玩家预制体必须挂载上述脚本,且每个脚本仅订阅自身PlayerInput的事件,确保输入触发逻辑与玩家实例绑定。
PlayerInput.playerIndex由Player Input Manager自动分配,是区分玩家的可靠标识。- 务必在脚本销毁时取消事件订阅,避免无效回调和内存泄漏。
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

