[英]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.