因此,我尝试将具有速度和重力的物理弹丸/子弹添加到一个简单的第一人称射击游戏中,而不是仅进行射线投射,如果客户碰到东西,则使用Command。经过一番尝试和错误之后,我发现将弹丸与对撞机配合使用并不是最佳的处理方法,因为对于快速移动的物体,其物理计算速度不够快。所以我疯了自己的子弹物理学,如下所示。
private float startingVelocity = 50f;
private float gravity = 9.81f;
private Vector3 forwardDirection;
private Vector3 previousPosition;
private Vector3 nextPosition;
private Vector3 movementDirection;
private Vector3 velocity;
void Start ()
{
previousPosition = transform.position;
forwardDirection = transform.forward.normalized;
velocity = forwardDirection*startingVelocity;
}
void Update ()
{
previousPosition = transform.position;
velocity += new Vector3(0f, -1f, 0f)*gravity*Time.deltaTime;
nextPosition = previousPosition + velocity*Time.deltaTime;
transform.position = nextPosition;
Debug.DrawLine(previousPosition, nextPosition, Color.white, 10f);
movementDirection = nextPosition - previousPosition;
if (movementDirection!=Vector3.zero)
{
transform.rotation = Quaternion.LookRotation(movementDirection);
}
CheckImpact(previousPosition, nextPosition);
}
CheckImpact函数实际上只是在两个位置之间进行射线广播,以检查弹丸撞击的方式是否存在墙壁或玩家。碰到东西时,会调用一个Command,服务器会对目标造成伤害。
子弹本身是这样生成的:
[Command]
void CmdShootProjectile(string projectilePath, Vector3 _position, Quaternion _rotation)
{
GameObject projectile = Instantiate(Resources.Load<GameObject>(projectilePath), _position, _rotation);
NetworkServer.Spawn(projectile);
客户端射击,命令在服务器上生成项目符号,然后为每个客户端生成项目符号,以便可以看到它。 这种方法的问题在于,服务器会计算子弹是否被击中,而这并不总是与玩家的状态保持一致。
我如何有效,可靠地处理弹丸?我能以某种方式让实际射击的客户计算子弹并检查它是否命中,而其他客户仍能看到子弹吗?
谢谢。
答案 0 :(得分:1)
不幸的是,几乎不可能有100%安全可靠的方法来做到这一点。但是,对此有相当多的研究(由Valve等公司的《 Counter Strike》等游戏公司进行。)
当前的共识是确实在服务器端而不是在客户端进行计算。有优点也有缺点。
优点:
缺点:
就我个人而言,我喜欢您的方法,现在应该还可以。随着游戏的进展以及对更好系统的需求,您可以对其进行更改。