处理 Coop 游戏物理(角色移动,命中......)
Handling Coop game physics (character movement, hit...)
我已经在网上搜索了一段时间以解决我的问题,但找不到足够的资源来帮助我。
我正在使用 UDP 库 https://github.com/RevenantX/LiteNetLib 在 Unity 3D 中开发一款合作 RPG 游戏,我设法建立了一个客户端-服务器连接,我在其中发送玩家移动的矢量(时间不应用计算 - 所以服务器可以自己处理它)到服务器,它计算角色应该在的新位置,然后我向所有玩家广播我发送到服务器的新的相同矢量所以他们还可以自己计算物理。
我 运行 遇到的问题是运动看起来很滞后,有时计算错误。
我不确定是因为我的本地 PlayerController 脚本还是因为网络不好,或者我实际上应该发送客户端的新绝对位置的糟糕设计。
我知道这是一个难题,我希望尝试自己创建多人游戏的开发人员能得到一些指导或专业知识,
我还要注意,作弊与我无关,因为这是一款合作游戏,而不是竞技游戏。
在此先感谢您的帮助。
这是我的本地 PlayerController 代码片段:
void Update()
{
// Get Input for axis
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
// Calculate the forward vector
Vector3 camForward_Dir = Vector3.Scale(UnityEngine.Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;
Vector3 move = v * camForward_Dir + h * UnityEngine.Camera.main.transform.right;
if (move.magnitude > 1f) move.Normalize();
// Calculate the rotation for the player
move = transform.InverseTransformDirection(move);
// Get Euler angles
float turnAmount = Mathf.Atan2(move.x, move.z);
transform.Rotate(0, turnAmount * RotationSpeed * Time.deltaTime, 0);
if (_characterController.isGrounded)
{
_moveDir = transform.forward * move.magnitude;
_moveDir *= Speed;
}
_moveDir.y -= Gravity * Time.deltaTime;
var delta = _moveDir * Time.deltaTime;
_characterController.Move(delta);
if (!IsMoving())
{
//_wasMoving = false;
return;
}
// we send the move direction so that the server and other client`s can calculate for themselves
OnPlayerMoved?.Invoke(_moveDir, Time.deltaTime);
}
正如我在评论中提到的,仍然需要有关此主题的帮助的人可能想查看此演示 https://github.com/RevenantX/NetGameExample 它演示了如何创建可以轻松应用于 3D 的 2D 播放器同步,代码属于到 RevenantX,
它依赖于他也为社区创建的 UDP 库。
我已经在网上搜索了一段时间以解决我的问题,但找不到足够的资源来帮助我。
我正在使用 UDP 库 https://github.com/RevenantX/LiteNetLib 在 Unity 3D 中开发一款合作 RPG 游戏,我设法建立了一个客户端-服务器连接,我在其中发送玩家移动的矢量(时间不应用计算 - 所以服务器可以自己处理它)到服务器,它计算角色应该在的新位置,然后我向所有玩家广播我发送到服务器的新的相同矢量所以他们还可以自己计算物理。
我 运行 遇到的问题是运动看起来很滞后,有时计算错误。
我不确定是因为我的本地 PlayerController 脚本还是因为网络不好,或者我实际上应该发送客户端的新绝对位置的糟糕设计。
我知道这是一个难题,我希望尝试自己创建多人游戏的开发人员能得到一些指导或专业知识,
我还要注意,作弊与我无关,因为这是一款合作游戏,而不是竞技游戏。
在此先感谢您的帮助。
这是我的本地 PlayerController 代码片段:
void Update()
{
// Get Input for axis
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
// Calculate the forward vector
Vector3 camForward_Dir = Vector3.Scale(UnityEngine.Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;
Vector3 move = v * camForward_Dir + h * UnityEngine.Camera.main.transform.right;
if (move.magnitude > 1f) move.Normalize();
// Calculate the rotation for the player
move = transform.InverseTransformDirection(move);
// Get Euler angles
float turnAmount = Mathf.Atan2(move.x, move.z);
transform.Rotate(0, turnAmount * RotationSpeed * Time.deltaTime, 0);
if (_characterController.isGrounded)
{
_moveDir = transform.forward * move.magnitude;
_moveDir *= Speed;
}
_moveDir.y -= Gravity * Time.deltaTime;
var delta = _moveDir * Time.deltaTime;
_characterController.Move(delta);
if (!IsMoving())
{
//_wasMoving = false;
return;
}
// we send the move direction so that the server and other client`s can calculate for themselves
OnPlayerMoved?.Invoke(_moveDir, Time.deltaTime);
}
正如我在评论中提到的,仍然需要有关此主题的帮助的人可能想查看此演示 https://github.com/RevenantX/NetGameExample 它演示了如何创建可以轻松应用于 3D 的 2D 播放器同步,代码属于到 RevenantX, 它依赖于他也为社区创建的 UDP 库。