Photon中RPC未通过网络传输数据 玩家射击效果仅本地可见
问题根源
- RPC方法
shoot中保留了if (!photonView.IsMine) return判断,非操作端玩家收到RPC请求后会直接终止执行,不会渲染射击效果 Input.GetButton("Fire1")输入判断放在了RPC方法内部,只有执行射击操作的本地玩家能触发输入条件,其他客户端永远无法走到渲染射击线的逻辑分支- 额外冗余问题:原代码每帧都发送RPC请求,会产生大量无效网络请求,严重浪费带宽
修复方案
- 将输入判断、射线检测逻辑全部放在本地操作端的Update中执行,不要放到RPC方法内
- 仅在检测到玩家按下射击键时才发送RPC,同时把射击线的起点、终点坐标作为参数传递给所有客户端
- RPC方法中仅保留渲染射击效果的逻辑,移除IsMine判断,所有收到RPC的客户端都执行渲染逻辑
修正后代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; public class playerShoot : MonoBehaviourPunCallbacks { public Transform shootPoint; public LineRenderer gunLine; public float range = 30f; RaycastHit hit; Ray ray; public PhotonView photonview; void Start() { gunLine = GetComponent<LineRenderer>(); photonview = PhotonView.Get(this); } void Update() { if (!photonView.IsMine) return; // 按下射击键时计算位置并发RPC if (Input.GetButtonDown("Fire1")) { ray.origin = shootPoint.position; ray.direction = transform.forward; Vector3 endPoint; if (Physics.Raycast(ray, out hit, range)) { endPoint = hit.point; Debug.Log(hit.point); } else { endPoint = ray.origin + ray.direction * range; } photonview.RPC("RenderShootEffect", RpcTarget.All, shootPoint.position, endPoint); } // 松开射击键时同步关闭射线 if (Input.GetButtonUp("Fire1")) { photonview.RPC("HideShootEffect", RpcTarget.All); } } [PunRPC] public void RenderShootEffect(Vector3 startPos, Vector3 endPos) { gunLine.enabled = true; gunLine.SetPosition(0, startPos); gunLine.SetPosition(1, endPos); } [PunRPC] public void HideShootEffect() { gunLine.enabled = false; } }
额外注意事项
- 如果需要射击线显示固定持续时间,可以在
RenderShootEffect中添加协程延迟调用HideShootEffect,不需要每帧发送RPC - 注意变量名大小写区分,自定义的
photonview和父类自带的photonView是两个变量,避免混淆导致空引用错误
内容的提问来源于stack exchange,提问作者user14553320
相关产品推荐
相关产品推荐

