简体   繁体   English

Unity - 一个客户端可以使用游戏手柄(网络代码和输入系统)控制所有玩家对象

[英]Unity - One client can control all player objects using gamepad (Netcode and Input System)

TL;DR Clients can control only their player objects with keyboard, but all players with gamepad (using Netcode for Game Objects, Unity Input System and a PS4 Controller) TL;DR 客户端只能使用键盘控制他们的玩家对象,但所有玩家都可以使用游戏手柄(使用 Netcode for Game Objects、Unity 输入系统和 PS4 控制器)

I am working on a multiplayer game and I am relatively new to multiplayer programming.我正在开发一款多人游戏,而且我对多人编程还比较陌生。 I am using Netcode for GameObjects.我正在为游戏对象使用网络代码。

I am using Unity Input System for handling inputs and I created 2 action maps currently.我正在使用 Unity 输入系统来处理输入,我目前创建了 2 个动作图。 One for movements (with keyboard and gamepad) and one for attacking (with keyboard, gamepad and mouse).一种用于移动(带有键盘和游戏手柄),一种用于攻击(带有键盘、游戏手柄和鼠标)。

I am trying to move the players in a Server Authoritative way;我正在尝试以服务器权威的方式移动玩家; thus, I am using Server RPCs for handling movements.因此,我使用服务器 RPC 来处理动作。

The issue I am having is that, when I play with a Gamepad (PS4 controller), one of the clients can control the others.我遇到的问题是,当我使用游戏手柄(PS4 控制器)玩游戏时,其中一个客户端可以控制其他客户端。 However, it works perfectly with Keyboard actions.但是,它与键盘操作完美配合。

The code I'm using for the player movement is below:我用于玩家移动的代码如下:

[RequireComponent(typeof(Rigidbody))]
public class PlayerMovement : NetworkBehaviour
{
    [SerializeField] private Rigidbody _rb;
    [SerializeField] private float movementSpeed = 10f;
    [SerializeField] private float jumpSpeed = 8f;

    Vector3 _movementVector;

    private PlayerInputActions playerInputActions;

    private PlayerInputActions PlayerInputActions
    {
        get
        {
            if(playerInputActions != null)
            {
                return playerInputActions;
            }
            return playerInputActions = new PlayerInputActions();
        }
    }

    public override void OnNetworkSpawn()
    {
        if(!IsOwner) { return; }
        PlayerInputActions.PlayerMovement.Movement.performed += ctx => SetMovement(ctx.ReadValue<Vector2>());
        PlayerInputActions.PlayerMovement.Movement.canceled += ctx => SetMovement(Vector2.zero);
        PlayerInputActions.PlayerMovement.Jump.performed += PerformJump;
    }

    public override void OnNetworkDespawn()
    {
        if (!IsOwner) { return; }
        PlayerInputActions.PlayerMovement.Movement.performed -= ctx => SetMovement(ctx.ReadValue<Vector2>());
        PlayerInputActions.PlayerMovement.Movement.canceled -= ctx => SetMovement(Vector2.zero);
        PlayerInputActions.PlayerMovement.Jump.performed -= PerformJump;
    }

    private void OnEnable() => PlayerInputActions.Enable();

    private void OnDisable() => PlayerInputActions.Disable();

    private void SetMovement(Vector2 inputVector) => _movementVector = new Vector3(inputVector.x, 0.0f, 0.0f);

    private void PerformJump(InputAction.CallbackContext obj)
    {
        if (!IsOwner) { return; }
        Vector3 jumpVector = Vector3.up;
        HandleJumpServerRpc(jumpVector);
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        if(!IsLocalPlayer) { return; }
        HandleMovement();
    }

    private void HandleMovement()
    {
        if (!IsOwner) { return; }
        HandleMovementServerRpc(_movementVector);
    }

    #region Server

    [ServerRpc]
    private void HandleMovementServerRpc(Vector3 movementVector)
    {
        if(Vector3.Distance(movementVector, Vector3.zero) > 0.000001f)
        {
            Debug.Log($"Owner ID: {OwnerClientId}");
            _rb.MovePosition(transform.position + movementVector * Time.deltaTime * movementSpeed);
        }
    }

    [ServerRpc]
    private void HandleJumpServerRpc(Vector3 jumpVector)
    {
        if (_rb.velocity.y == 0f)
        {
            _rb.AddForce(jumpVector * jumpSpeed, ForceMode.Impulse);
        }
            
    }

    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log($"Collided with: {collision.gameObject.name}");
    }

    #endregion
}

And following is the Action Map I created for movement:以下是我为运动创建的动作 Map: 行动图

I thought the issue is with the Unity Input System event subscriptions, but I could not find a fix so far for it.我认为问题出在 Unity Input System 事件订阅上,但到目前为止我找不到解决方法。

Any help is appreciated!任何帮助表示赞赏!

Im not sure if this will work but i did我不确定这是否可行,但我做到了

    public override void OnNetworkSpawn(){
    if (!IsOwner) Destroy(this); 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM