【发布时间】:2022-08-15 02:08:33
【问题描述】:
TL;DR 客户端只能使用键盘控制他们的玩家对象,但所有玩家都可以使用游戏手柄(使用游戏对象的网络代码、Unity 输入系统和 PS4 控制器)
我正在开发一款多人游戏,而且我对多人编程还比较陌生。我正在为游戏对象使用网络代码。
我正在使用 Unity 输入系统来处理输入,我目前创建了 2 个动作图。一种用于移动(带有键盘和游戏手柄),一种用于攻击(带有键盘、游戏手柄和鼠标)。
我正在尝试以服务器权威的方式移动玩家;因此,我使用服务器 RPC 来处理动作。
我遇到的问题是,当我使用游戏手柄(PS4 控制器)玩游戏时,其中一个客户端可以控制其他客户端。但是,它与键盘操作完美配合。
我用于玩家移动的代码如下:
[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
}
我认为问题出在 Unity Input System 事件订阅上,但到目前为止我找不到解决方法。
任何帮助表示赞赏!
标签: c# unity3d multiplayer