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

Unity3D与Photon:鼠标控制脚本引发多人鼠标输入异常

3D俯视角游戏中Photon PUN玩家鼠标旋转同步异常问题

问题描述

我是C#和Photon PUN的新手,正在开发一款3D俯视角游戏,核心需求是玩家根据鼠标位置进行角色旋转。目前遇到一个异常问题:当一名玩家移动鼠标时,另一名玩家的角色也会跟着旋转,仅存在轻微延迟。

我的项目设置:

  • Mouse Controller脚本挂载在玩家预制体的空子对象上,相机为玩家预制体的子对象
  • 曾尝试将脚本直接挂载到玩家预制体上,问题依旧
  • 玩家移动和相机同步功能正常,唯独鼠标旋转的同步出现异常

已尝试的解决方案:

  • 将鼠标控制函数合并到玩家控制器脚本中
  • 在Awake()、Start()和Update()中调整PhotonView.IsMine的检查逻辑
  • 将脚本直接挂载到带有Photon View组件的玩家预制体上
    以上方案均未解决问题。

附当前Mouse Controller脚本代码:

[SerializeField] private LayerMask groundMask;
public bool mouseOnGround;
public Vector3 mousePosition;
public Vector3 aimDirection;
public Camera playerCam;
public float myMouseInput;
public PhotonView PV;

// Start is called before the first frame update
void Start()
{
    PV = GetComponent<PhotonView>();

    ///THIS HAS NOT WORKED AND SIMPLY PREVENTS PLAYERS FROM ROTATING   
    if (!photonView.IsMine)
    {
        {
            Destroy(this);
        }
    }

    if ((photonView.IsMine))
    {
        playerCam = GetComponentInParent<Camera>();
    }
}

// Update is called once per frame
void Update()
{
    if(this.photonView.IsMine)
    {
        if (mouseOnGround == true)
        {
            MouseAim();
            GetMousePosition();
        }
    }
}

public void MouseAim()
{
    if (this.photonView.IsMine)
    {
        if (mouseOnGround == true)
        {
            aimDirection = mousePosition - transform.position;
            aimDirection.y = 0;
            transform.forward = aimDirection;
        }
    }
}

public void GetMousePosition()
{
    if (this.photonView.IsMine)
    {
        var Ray = playerCam.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(Ray, out var hitInfo, Mathf.Infinity, groundMask))
        {
            mouseOnGround = true;
            mousePosition = hitInfo.point;
            Debug.Log(mousePosition);
        }
        else
        {
            mouseOnGround = false;
            mousePosition = Vector3.zero;
        }
    }
}

解决方案

问题根源

你的代码中虽然加入了PhotonView.IsMine检查,但角色旋转操作直接修改了transform.forward,而玩家预制体上的**Photon Transform View组件默认会自动同步所有变换属性(包括旋转)**到其他客户端。这就导致本地玩家的旋转被同步给了所有玩家,出现“别人动鼠标我也转”的问题。

具体修复步骤

  1. 修正脚本中的语法与逻辑错误

    • Start()方法里销毁非本地脚本的代码有多余大括号,修正后确保非本地客户端直接销毁脚本,避免冗余逻辑:
      void Start()
      {
          PV = GetComponent<PhotonView>();
      
          if (!PV.IsMine)
          {
              Destroy(this);
              return;
          }
      
          playerCam = GetComponentInParent<Camera>();
      }
      
    • Update()中逻辑顺序颠倒,应该先获取鼠标位置,再执行旋转操作:
      void Update()
      {
          if (PV.IsMine)
          {
              GetMousePosition(); // 先更新鼠标位置
              if (mouseOnGround)
              {
                  MouseAim(); // 再根据最新位置旋转
              }
          }
      }
      
  2. 禁用Photon Transform View的自动旋转同步
    打开玩家预制体上的Photon Transform View组件:

    • 在Transform Synchronization选项中选择Manual Sync
    • 或者展开Position Synchronization,只勾选位置同步,取消Rotation Synchronization的勾选,避免自动同步旋转属性覆盖手动控制。
  3. 通过RPC手动同步旋转(可选,用于让其他玩家看到本地玩家的旋转)
    如果需要其他玩家看到本地玩家的旋转状态,不要依赖自动同步,改用Photon的RPC机制主动同步:

    public void MouseAim()
    {
        if (!PV.IsMine) return;
    
        if (mouseOnGround)
        {
            aimDirection = mousePosition - transform.position;
            aimDirection.y = 0;
            transform.forward = aimDirection;
            // 发送RPC给其他客户端同步旋转方向
            PV.RPC(nameof(SyncRotation), RpcTarget.Others, aimDirection);
        }
    }
    
    [PunRPC]
    private void SyncRotation(Vector3 targetDir)
    {
        transform.forward = targetDir;
    }
    

    这样只有本地玩家计算旋转逻辑,然后主动将旋转状态同步给其他客户端,不会出现交叉同步的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:05:15