权威服务器拒绝任何动作。 [团结,光子螺栓]

时间:2019-12-24 12:42:27

标签: unity3d networking client-server rollback photon

我一直试图在Unity 2018.4.9f1上使用Photon Bolt制作一个简单的在线fps原型。 这是问题所在:

Link to gif

如您所见,当尝试在客户端上移动时,服务器会丢弃对Player prefab变换的任何修改,从而导致客户端尝试移动但又被传送回(0,0)。由于Photon Bolt的回滚机制,每帧还多次应用客户的输入。

如您所见,这些都不是监听服务器上播放器可以正常移动的问题。

这是我的光子螺栓的设置:

Link to image

这是我的PlayerState状态:

Link to image

这是我的播放器预制件:

Link to image

我的完整存储库可在此处的“资产/游戏文件/脚本”下的相关文件中找到:

https://github.com/LoshkinOleg/NetworkingRattrapage

以下是相关代码:

[BoltGlobalBehaviour(BoltNetworkModes.Server)]
class GameManager : GlobalEventListener
{
    Dictionary<BoltConnection, BoltEntity> clientPlayers = new Dictionary<BoltConnection, BoltEntity>();
    BoltEntity serverPlayer = null;

    public override void BoltStartDone()
    {
        // Instanciate a player prefab for the listen server.
        serverPlayer = BoltNetwork.Instantiate(BoltPrefabs.Player, Vector3.up, Quaternion.identity);
        serverPlayer.TakeControl();
    }

    public override void Connected(BoltConnection connection)
    {
        // Instanciate player prefabs for new clients.
        clientPlayers.Add(connection, BoltNetwork.Instantiate(BoltPrefabs.Player, Vector3.up, Quaternion.identity));
        clientPlayers[connection].AssignControl(connection);
    }

    public override void Disconnected(BoltConnection connection)
    {
        // Clean up after disconnected player.
        clientPlayers[connection].ReleaseControl();
        clientPlayers[connection].DestroyDelayed(0.0f);
        clientPlayers.Remove(connection);
    }
}
public class PlayerController : EntityBehaviour<IPlayerState>
{
    struct Input
    {
        public float mouseX;
        public bool left;
        public bool up;
        public bool right;
        public bool down;
    }
    struct State
    {
        public Vector3 position;
        public Quaternion rotation;
    }

    // Player values.
    [SerializeField] [Range(0.0f, float.MaxValue)] float acceleration = 5.0f;
    [SerializeField] [Range(0.0f, float.MaxValue)] float maxSpeed = 10.0f;
    [SerializeField] [Range(0.0f, float.MaxValue)] float mouseSensitivity = 2.0f;
    [SerializeField] [Range(0.0f, 180.0f)] float fieldOfView = 90.0f;

    // Player camera to instanciate.
    [SerializeField] GameObject cameraPrefab = null;

    // Network related.
    Input input;
    State playerState;

    // Bolt inherited.
    public override void Attached()
    {
        // Sync the transforms.
        state.SetTransforms(state.StateTransform, transform);
    }
    public override void ControlGained()
    {
        // Instanciate a camera for the player.
        var cameraTransform = Instantiate(cameraPrefab).transform;
        cameraTransform.SetPositionAndRotation(transform.position + transform.up, transform.rotation);
        cameraTransform.SetParent(transform);
        cameraTransform.gameObject.GetComponent<Camera>().fieldOfView = fieldOfView;

        playerState.position = transform.position;
        playerState.rotation = transform.rotation;
    }
    public override void SimulateController()
    {
        input.mouseX = UnityEngine.Input.GetAxisRaw("Mouse X");

        var horizontal = UnityEngine.Input.GetAxisRaw("Horizontal");
        var vertical = UnityEngine.Input.GetAxisRaw("Vertical");
        input.left = horizontal < 0.0f;
        input.up = vertical > 0.0f;
        input.right = horizontal > 0.0f;
        input.down = vertical < 0.0f;

        var cmd = MovementCommand.Create();
        cmd.MouseX = input.mouseX;
        cmd.Left = input.left;
        cmd.Up = input.up;
        cmd.Right = input.right;
        cmd.Down = input.down;
        entity.QueueInput(cmd);
    }

    public override void ExecuteCommand(Command command, bool resetState)
    {
        MovementCommand cmd = command as MovementCommand;

        // Process command.
        if (resetState) // Ran on controller only.
        {
            transform.position = cmd.Result.Position;
            transform.rotation = cmd.Result.Rotation;
            playerState.position = cmd.Result.Position;
            playerState.rotation = cmd.Result.Rotation;
        }
        else // ran on controller and owner.
        {
            // Move.
            var newMovement = Vector3.zero;
            if (input.left) newMovement -= transform.right;
            if (input.up) newMovement += transform.forward;
            if (input.right) newMovement += transform.right;
            if (input.down) newMovement -= transform.forward;
            newMovement.Normalize();

            newMovement *= acceleration * BoltNetwork.FrameDeltaTime;
            newMovement = Vector3.ClampMagnitude(newMovement, maxSpeed);

            playerState.position += newMovement;

            // Rotate.
            playerState.rotation *= Quaternion.Euler(new Vector3(0, input.mouseX, 0) * mouseSensitivity);

            // Apply movement and rotation.
            cmd.Result.Position = playerState.position;
            cmd.Result.Rotation = playerState.rotation;
            transform.position = playerState.position;
            transform.rotation = playerState.rotation;
        }
    }
}

一段时间以来,我一直在尝试实现权威性运动,而我刚开始感觉像苍蝇在窗户上敲打。 我了解所有权和回滚存在一些问题,但我无法充分理解Bolt的系统来修复这些错误。

我试图阅读他们的文档,他们的API参考以及他们的教程的源代码,但是我仍然不明白。

非常感谢您提出任何建议,

0 个答案:

没有答案