Unity卡牌游戏开发问题:无法从Deck列表移除卡牌
问题原因及解决方法
核心问题
你没法从Deck里移除卡牌的根本原因是:你尝试移除的对象根本不在Deck列表里。
看你的DrawCard函数:
GameObject playerCard = Instantiate(cards[Random.Range(0, cards.Count)], new Vector3(0, 0, 0), Quaternion.identity);
这里用Instantiate创建了一个全新的GameObject实例,返回的是这个新对象,但Deck列表里存的是原始的卡牌预制体/对象。调用Deck.Remove(PickedCard)时,系统在Deck里找不到这个新实例,自然没法移除原本的卡牌。
修正方案
先从Deck里拿到原始卡牌,再实例化生成显示用的对象,接着移除Deck里的原始卡牌,最后把实例化的对象加入弃牌堆(如果你的弃牌堆需要存显示用对象的话)。
调整后的代码如下:
// 修改DrawCard,传入原始卡牌,返回实例化后的显示对象 public GameObject DrawCard(GameObject originalCard) { GameObject playerCard = Instantiate(originalCard, new Vector3(0, 0, 0), Quaternion.identity); playerCard.transform.SetParent(PlayerArea.transform, false); return playerCard; } public void StartCards() { for(var i = 0; i < 2; i++) { // 先随机获取Deck里原始卡牌的索引 int randomIndex = Random.Range(0, Deck.Count); GameObject originalCard = Deck[randomIndex]; // 实例化得到玩家区域显示的卡牌 PickedCard = DrawCard(originalCard); // 从Deck里移除原始卡牌(用索引移除更可靠) Deck.RemoveAt(randomIndex); // 将实例化的卡牌加入弃牌堆 DiscardPile.Add(PickedCard); Debug.Log(DiscardPile[i]); // 注意:循环第二次时Deck长度已减1,Deck[1]可能触发索引越界,建议改成Debug.Log(Deck.Count)验证移除效果 } }
额外提示
- 如果你弃牌堆需要存原始卡牌而非实例化对象,把
DiscardPile.Add(PickedCard)改成DiscardPile.Add(originalCard)即可。 - 循环里的
Debug.Log(Deck[1])存在越界风险:当你移除第一张卡牌后,Deck长度会减1,如果初始Deck只有2张,第二次循环时Deck[1]会报错,换成打印Deck的当前数量更稳妥。
内容的提问来源于stack exchange,提问作者Theo Nimz
相关产品推荐
相关产品推荐

