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

Unity Mirror问题:实例化对象参数生成时无法同步到客户端

问题描述

我用Unity Mirror开发多人卡牌游戏,实例化卡牌后调用RandomizeCard方法随机设置属性,主机端显示正常,但客户端的卡牌还是默认值,就像这个方法没执行过一样。试了改实例化后卡牌的旋转属性,能正常同步到客户端,但Card脚本里的属性同步不了,怎么把卡牌信息传给客户端?

生成卡牌的代码

GameObject card = Instantiate(card1, new Vector2(0, 0), Quaternion.identity);
Card cardScript = card.GetComponent<Card>();
cardScript.RandomizeCard();
NetworkServer.Spawn(card, connectionToClient);

RandomizeCard方法(Card脚本内)

public void RandomizeCard()
{
    Sprite _randomImage = cardImages[Random.Range(0, cardImages.Count)];
    cardImage.sprite = _randomImage;
    cardName = _randomImage.name;
}
解决方案

1. 给Card脚本添加NetworkBehaviour并标记同步变量

Mirror中只有继承NetworkBehaviour的脚本才能实现网络同步,且需要同步的字段必须用[SyncVar]标记。注意Sprite无法直接序列化同步,改用索引同步:

public class Card : NetworkBehaviour // 必须继承NetworkBehaviour
{
    public Sprite[] cardImages;
    public Image cardImage;

    [SyncVar(hook = nameof(OnCardNameUpdated))]
    public string cardName;
    [SyncVar(hook = nameof(OnCardSpriteUpdated))]
    public int spriteIndex;

    public void RandomizeCard()
    {
        if (!isServer) return; // 仅主机端执行随机逻辑
        spriteIndex = Random.Range(0, cardImages.Length);
        cardName = cardImages[spriteIndex].name;
    }

    // SyncVar钩子:客户端收到spriteIndex更新时触发
    void OnCardSpriteUpdated(int oldIndex, int newIndex)
    {
        cardImage.sprite = cardImages[newIndex];
    }

    // SyncVar钩子:客户端收到cardName更新时触发
    void OnCardNameUpdated(string oldName, string newName)
    {
        // 这里可以更新卡牌名称的UI显示
    }
}

2. 确保随机逻辑仅在主机执行

在RandomizeCard中加入isServer判断,避免客户端本地执行随机逻辑覆盖同步过来的主机数据。你原代码的调用顺序没问题,但必须加这个判断。

3. 给卡牌预制体挂载NetworkIdentity

卡牌预制体上必须添加NetworkIdentity组件,保持默认设置即可(不要勾选Server Only),否则Mirror无法识别为网络同步对象。

4. 客户端与主机资源保持一致

客户端的cardImages数组必须和主机完全匹配,Sprite的索引、名称、路径都要一致,否则同步索引后客户端会加载错误的图片。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:07:18