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

Unity中无法正确打印数组最后一个元素问题求助

问题分析与解决方案

你的代码出现最后一个物品显示为empty_item的问题,核心是逻辑顺序错误、缺少关键标签赋值和错误使用线程阻塞导致的,下面一步步拆解并修复:

核心问题点

  1. 执行顺序颠倒:打印逻辑在替换第8个物品的Sprite之前就触发了——遍历前7个非空slot时,counter累计到7直接触发打印,此时第8个slot还没完成更新,获取的数组自然不包含新物品。
  2. 缺少标签赋值:替换Sprite后,没有给对应的slot子物体添加ChoosenItem标签,导致FindGameObjectsWithTag无法识别新收集的物品。
  3. 错误使用Thread.Sleep:Unity主线程中使用Thread.Sleep会阻塞所有游戏更新(包括UI渲染),即使替换了Sprite,阻塞期间也不会生效,打印时还是旧内容。

修复后的完整代码

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class PickUpItem : MonoBehaviour, IInteractable {
    public string DisplaySprite;
    public string DisplayImage;
    public static GameObject[] PlayerItems = new GameObject[8];

    public void Interact(DisplayImage currentDisplay) {
        StartCoroutine(ItemPickUpCoroutine());
    }

    void Start() { }
    void Update() { }

    private IEnumerator ItemPickUpCoroutine() {
        GameObject inventorySlots = GameObject.Find("Slots");
        bool itemAdded = false;

        // 先完成物品添加与标签设置
        foreach (Transform slot in inventorySlots.transform) {
            Image slotImage = slot.GetChild(0).GetComponent<Image>();
            if (slotImage.sprite.name == "empty_item") {
                // 替换物品Sprite
                slotImage.sprite = Resources.Load<Sprite>("Inventory Items/" + DisplaySprite);
                // 给当前slot子物体添加标签(关键:让Find方法能识别)
                slotImage.gameObject.tag = "ChoosenItem";
                Destroy(gameObject);
                itemAdded = true;
                break;
            }
        }

        // 物品添加完成后,统计已收集数量
        GameObject[] collectedItems = GameObject.FindGameObjectsWithTag("ChoosenItem");
        
        // 满8个时延迟打印(用协程避免阻塞)
        if (collectedItems.Length == 8) {
            Debug.Log("You have chosen all your items.");
            // 等待5秒,期间Unity正常处理UI更新
            yield return new WaitForSeconds(5f);
            Debug.Log("Waiting 5 seconds.");
            
            PlayerItems = collectedItems;
            for (int j = 0; j < PlayerItems.Length; j++) {
                Debug.LogFormat("Item[{0}] = {1}", j, PlayerItems[j].GetComponent<Image>().sprite.name);
            }
        }
    }
}

关键修复说明

  • 用协程替代Thread.Sleep:WaitForSeconds不会阻塞主线程,Unity可以在等待期间完成UI渲染和状态更新,确保打印时所有物品都已正确显示。
  • 调整逻辑顺序:先完成物品的Sprite替换和标签赋值,再统计已收集数量,确保打印操作在所有更新完成后执行。
  • 添加标签赋值:替换Sprite后给slot子物体设置ChoosenItem标签,让FindGameObjectsWithTag能正确识别所有已收集物品。
  • 简化计数逻辑:直接用FindGameObjectsWithTag的长度统计已收集物品数,避免手动计数出错。

修改后,收集满8个物品时会先完成最后一个物品的更新,等待5秒后再打印所有物品,就能得到你预期的输出结果。

内容的提问来源于stack exchange,提问作者Jeremiah O Sullivan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:18:17