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

Mirror框架中修改名称后客户端无报错断开连接问题求助

解决Mirror框架客户端修改名称断开连接的问题

你的问题核心是对Command方法的执行上下文理解错误:[Command]标记的方法是在服务器端执行的,而你在CmdChangeName里直接访问客户端的TMP_InputField组件tmpf——服务器上不存在这个UI对象,会触发空引用异常,导致客户端被强制断开,这就是你看到“客户端未执行逻辑就终止”的原因。


解决方案

不要在Command方法中访问客户端本地UI组件,而是将输入的名字作为参数传递给Command,服务器端接收参数后直接赋值给SyncVar,通过SyncVar的Hook自动同步到所有客户端。

修改后的完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using TMPro;

public class PlayerMovement : NetworkBehaviour
{
    public float speed;
    float x, y;
    Rigidbody2D rb;
    Animator animator;
    public TMP_InputField tmpf;
    public TMP_Text nameText;

    [SyncVar(hook = nameof(DisplayName))]
    public string _name = "00";

    void DisplayName(string oldName, string newName)
    {
        nameText.text = newName;
    }

    void Start()
    {
        if (!isLocalPlayer) return;
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
        tmpf = GameObject.Find("NameIF").GetComponent<TMP_InputField>();
    }

    void Update()
    {
        if (!isLocalPlayer) return;
        x = Input.GetAxis("Horizontal");
        y = Input.GetAxis("Vertical");
        rb.velocity = new Vector2(x * speed, y * speed);
        animator.SetFloat("horizontal", x);
        animator.SetFloat("vertical", y);

        if (Input.GetKeyDown(KeyCode.KeypadEnter))
        {
            // 将输入框文本作为参数传入Command
            if (!string.IsNullOrEmpty(tmpf.text))
            {
                CmdChangeName(tmpf.text);
            }
        }
    }

    [Command]
    public void CmdChangeName(string newName)
    {
        // 服务器端直接使用传入的参数,避免访问客户端UI
        // 可选:添加输入验证,比如限制长度、过滤非法字符
        if (newName.Length > 10)
        {
            newName = newName.Substring(0, 10);
        }
        _name = newName;
    }
}

关键改动说明

  1. 传递参数给Command:客户端调用CmdChangeName时,把tmpf.text作为参数传入,让服务器直接使用这个字符串,避免访问客户端本地UI组件。
  2. 服务器端输入验证:增加了简单的长度限制,避免过长名字导致显示问题,你可以根据需求扩展验证逻辑(比如过滤特殊字符)。
  3. 保留SyncVar同步逻辑:SyncVar的Hook方法DisplayName会在_name值改变时自动在所有客户端(包括服务器)执行,确保名字文本同步更新。

额外注意事项

  • 开启客户端权限后,本地玩家可以直接调用Command方法,但服务器永远无法访问客户端的本地GameObject或组件,所有需要传递给服务器的数据都必须通过参数传递。
  • 确保NameIF这个UI对象在每个客户端的场景中都存在,且只有本地玩家会执行Start里的初始化逻辑(因为有!isLocalPlayer判断)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:15:33