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
相关产品推荐
相关产品推荐

