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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:12:44