You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity Photon多人游戏如何实现不同玩家物体同时独立旋转同步

问题根因

当前枪械旋转脚本未做Photon网络所有权校验,所有客户端运行时,无论枪械归属哪个玩家,都会直接读取本地鼠标输入修改所有枪械对象的Transform;同时本地修改的远端玩家枪械状态,会持续被Photon下发的远端同步数据覆盖,最终出现所有枪械都跟随本地鼠标旋转、多端状态不同步的异常。

修复逻辑

遵循Photon多人开发的核心规则:仅对象的所属客户端有权限修改该网络对象的状态,其余客户端只接收网络同步的状态数据,不做本地输入驱动的修改,按以下步骤调整:

  • 确认玩家预制体、枪械子物体上正确挂载PhotonView组件,枪械的旋转、位置参数加入PhotonView的同步观测列表
  • 在枪械旋转脚本中增加所有权判断,仅当枪械归属本地玩家时,才执行鼠标输入读取、旋转计算、Transform修改逻辑
  • 远端玩家的枪械不执行任何本地控制逻辑,直接渲染Photon同步过来的旋转、位置状态即可
修复后参考代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class gunRotation : MonoBehaviour
{
    bool nf;
    bool f;
    bool l = true;
    private PhotonView pv;

    void Start()
    {
        // 枪械为玩家子物体时,获取父节点上的PhotonView组件;若枪械自身挂载PhotonView,可直接GetComponent<PhotonView>()
        pv = GetComponentInParent<PhotonView>();
    }

    public void FixedUpdate()
    {
        // 非本地玩家所属枪械,直接跳过本地控制逻辑,等待网络同步状态
        if (!pv.IsMine) return;
        
        //rotates the gun
        Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        float rotationZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
        difference.Normalize();
        transform.rotation = Quaternion.Euler(0f, 0f, rotationZ);

        if (rotationZ < -90 || rotationZ > 90)
        {
            if (gameObject.transform.eulerAngles.y == 0)
            {
                transform.localRotation = Quaternion.Euler(180, 0, -rotationZ);
            }
            else if (gameObject.transform.eulerAngles.y == 180)
            {
                transform.localRotation = Quaternion.Euler(180, 180, -rotationZ);
            }
        }
        // helps gun switch pos
        if (gameObject.transform.eulerAngles.y == 0 && l == true)
        {
            nf = true;
            l = false;
        }


        // switch gun pos
        if (gameObject.transform.eulerAngles.y == 0 && nf == true)
        {
            transform.position = new Vector3(gameObject.transform.position.x + 1.123f, gameObject.transform.position.y, gameObject.transform.position.z);
            nf = false;
            f = true;
        }
        else if (gameObject.transform.eulerAngles.y == 180 && f == true)
        {
            transform.position = new Vector3(gameObject.transform.position.x - 1.123f, gameObject.transform.position.y, gameObject.transform.position.z);
            f = false;
            nf = true;
        }
    }
}
额外注意事项

所有玩家输入驱动的逻辑(移动、射击、道具交互等)都必须加PhotonView.IsMine判断,禁止非所属客户端修改网络对象状态,否则会持续出现状态冲突、同步抖动、逻辑异常的问题。如果需要低延迟的远端表现,可以单独做客户端侧的预测插值,不要直接修改同步目标的Transform值。

内容的提问来源于stack exchange,提问作者Creamy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:34:12