You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:15:16