我有一个简单的FPS,玩家可以开枪。我希望客户看到弹孔。我试图通过在客户端尝试触发枪时调用服务器端方法来实现此目的。然后服务器端方法应该从玩家相机进行光线投射并产生一个弹孔供所有人查看..
我可以通过将播放器作为参数传递给服务器方法来部分工作。但是,由于我的光线投射需要基于玩家相机完成,弹孔最终会出现在角色高度,因为它使用的是玩家而不是相机。
它不允许我通过相机。我还尝试创建一个名为bullet spawn的空游戏对象并传递它,但我得到的是“对象引用未设置为对象的实例”。对于我尝试传递给服务器端方法的玩家的任何子元素,这个相同的错误似乎浮出水面。
我不确定实现这一目标的正确方法。
{{1}}
答案 0 :(得分:0)
以这种方式思考。你需要什么来开火你的武器?你需要射击点和射击方向(在你的简单情况下)。所以尽量传递这些信息。您的CmdFire应该看起来像void CmdFire(Vector3 firingPoint,Vector3 firingDirection)。请记住,当您通过播放器游戏对象时,它会被序列化并发送到服务器,从而导致大量不必要的网络流量。坚持使用值类型和命令的简单对象。
这最终促成了我的解决方案。谢谢你的建议。我只是按照你的建议传递了两个Vector3参数,它们代表了光线投射的位置和方向。我现在可以从客户端和服务器上进行拍摄,并查看两者上的弹孔。以下是修复它的代码,以防以后有人遇到此问题:
void Update() {
if (isLocalPlayer) {
if (Input.GetButton("Fire1")) {
Vector3 FiringSpot = PlayerCam.transform.position;
Vector3 FireDirection = PlayerCam.transform.forward;
CmdFire(FiringSpot, FireDirection);
}
}
}
[Command]
void CmdFire(Vector3 firingPoint, Vector3 firingDirection) {
Ray shooterRay = new Ray(firingPoint, firingDirection);
if (Physics.Raycast(shooterRay, out Hit, 10000)) {
GameObject Bullet_Hole = (GameObject)Instantiate(bullet_Hole_Prefab, Hit.point, Quaternion.FromToRotation(Vector3.up, Hit.point));
NetworkServer.Spawn(Bullet_Hole);
Destroy(Bullet_Hole, 10);
}
}