我一直试图在Unity 2018.4.9f1上使用Photon Bolt制作一个简单的在线fps原型。 这是问题所在:
如您所见,当尝试在客户端上移动时,服务器会丢弃对Player prefab变换的任何修改,从而导致客户端尝试移动但又被传送回(0,0)。由于Photon Bolt的回滚机制,每帧还多次应用客户的输入。
如您所见,这些都不是监听服务器上播放器可以正常移动的问题。
这是我的光子螺栓的设置:
这是我的PlayerState状态:
这是我的播放器预制件:
我的完整存储库可在此处的“资产/游戏文件/脚本”下的相关文件中找到:
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参考以及他们的教程的源代码,但是我仍然不明白。
非常感谢您提出任何建议,