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

Unity UNET客户端无法移动问题技术求助

解决UNET多人FPS本地玩家无法移动的问题

Hey there! Let's get your local player moving again. The main issue with your current setup is that you haven't properly tied your PlayerMotor to UNET's network authority rules—Local Player Authority means only the client that owns the player object can control it, and your script isn't enforcing that check. Let's walk through the fixes step by step.

关键修改步骤

1. 切换到NetworkBehaviour并添加必要命名空间

UNET网络脚本必须继承自NetworkBehaviour(而非普通的MonoBehaviour),这样才能访问isLocalPlayer这类网络专属属性。同时需要引入UnityEngine.Networking命名空间。

2. 限制控制逻辑仅在本地玩家执行

所有输入处理和移动代码都应该只在当前玩家是本地客户端所属对象时运行。我们会添加isLocalPlayer检查,并使用[ClientCallback]确保代码只在客户端执行。

3. 修正后的完整PlayerMotor脚本

以下是包含所有必要修复的更新脚本:

using UnityEngine;
using UnityEngine.Networking; // UNET网络类必备命名空间

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(NetworkIdentity))] // 确保对象拥有NetworkIdentity组件
public class PlayerMotor : NetworkBehaviour { // 继承NetworkBehaviour而非MonoBehaviour
    private Vector3 velocity;
    private Rigidbody rb;
    [SerializeField] private Camera playerCamera;

    private void Start(){
        rb = GetComponent<Rigidbody>();
        
        // 为非本地玩家隐藏相机,避免多相机渲染冲突
        if (!isLocalPlayer){
            playerCamera.gameObject.SetActive(false);
        }
    }

    // 仅在客户端运行输入逻辑,且仅针对本地玩家
    [ClientCallback]
    private void Update(){
        if (!isLocalPlayer) return; // 如果不是本地玩家直接退出
        
        // 示例输入处理(替换为你实际的输入逻辑)
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        Vector3 moveDirection = transform.right * horizontal + transform.forward * vertical;
        
        SetVelocity(moveDirection.normalized * 5f); // 根据需要调整移动速度
    }

    public void SetVelocity(Vector3 _velocity){
        velocity = _velocity;
    }

    // 仅在客户端运行移动逻辑,且仅针对本地玩家
    [ClientCallback]
    private void FixedUpdate(){
        if (!isLocalPlayer) return;
        PerformMovement();
    }

    private void PerformMovement(){
        if (velocity != Vector3.zero){
            rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
        }
    }
}

额外检查项

请确保以下配置也已正确设置:

  • 玩家预制体设置:确认玩家预制体的NetworkIdentity组件已勾选Local Player Authority(你提到已开启,但建议再次核对)。
  • 可生成预制体列表:将玩家预制体添加到NetworkManager的Spawn Info > Registered Spawnable Prefabs中,否则服务器无法正确生成玩家对象。
  • 刚体设置:确保玩家的Rigidbody未勾选Is Kinematic(否则MovePosition会失效)。
  • 网络同步组件:给玩家预制体添加NetworkTransform组件,自动将本地玩家的位置/旋转同步给其他客户端。

修改生效原因

  • NetworkBehaviour让我们能访问isLocalPlayer属性,从而将控制逻辑限制在本地玩家对象上。
  • [ClientCallback]确保Update和FixedUpdate等方法仅在客户端运行,不会在服务器执行。
  • 隐藏非本地玩家的相机,避免场景中多个激活相机导致的渲染冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:52:11