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

Unity技术问询:如何在不同场景间传递已设置的背包物品Sprite

Hey there! Let's break down how to fix your cross-scene inventory sprite issue step by step.

First, let's clarify why your current setup isn't working:

  • Your Items script isn't attached to any scene GameObject, so DontDestroyOnLoad(this) does nothing (it only works on objects that exist in the scene).
  • When you switch scenes, all non-persistent objects get destroyed, so your item sprite data vanishes with them. Static variables can work for this, but a dedicated persistent manager is cleaner and easier to maintain for inventory systems.

Here's a reliable solution using a singleton persistent manager—this is the go-to approach for cross-scene data sharing in Unity:

Step 1: Create a Persistent Inventory Data Manager

Make a new script called InventoryDataManager, attach it to an empty GameObject in your initial scene (like your main menu or first level), and use this code:

using UnityEngine;
using System.Collections.Generic;

public class InventoryDataManager : MonoBehaviour
{
    // Singleton instance - access this from anywhere in your code
    public static InventoryDataManager Instance { get; private set; }

    // Store all picked items here (custom struct holds all needed data)
    public List<PickedItem> CollectedItems = new List<PickedItem>();

    // Struct to hold cross-scene item data
    [System.Serializable]
    public class PickedItem
    {
        public int itemID;
        public string itemName;
        public string itemDescription;
        public Sprite itemSprite;
    }

    private void Awake()
    {
        // Ensure only one instance exists, and it survives scene loads
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    // Add a new item to the persistent inventory
    public void AddCollectedItem(int id, string name, string desc, Sprite sprite)
    {
        // Prevent duplicate items (optional, adjust based on your needs)
        var existingItem = CollectedItems.Find(item => item.itemID == id);
        if (existingItem == null)
        {
            CollectedItems.Add(new PickedItem
            {
                itemID = id,
                itemName = name,
                itemDescription = desc,
                itemSprite = sprite
            });
        }
    }
}

Step 2: Update Your Items Script to Save Data to the Manager

Modify your Items script to send item data to the manager when picked up (I'll assume you use a trigger for pickup—adjust to your actual pickup logic):

public class Items : MonoBehaviour { 
    public string ItemName; 
    public string ItemText; 
    public int itemInList; 
    public Sprite itemSprite; 
    public Sprite blueberrySprite; 
    public Sprite cheesecakeSprite; 
    public Sprite whitebreadSprite; 
    public Sprite cookiesSprite; 

    // Example pickup logic (triggered when player touches the item)
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            // Set item data first
            ItemList();
            // Save data to the persistent manager
            InventoryDataManager.Instance.AddCollectedItem(itemInList, ItemName, ItemText, itemSprite);
            // Remove the item from the scene after pickup
            Destroy(gameObject);
        }
    }

    public void ItemList() { 
        if(itemInList == 1) { 
            ItemName = "Cheesecake"; 
            ItemText = "A delishious Juicy Cheesecake"; 
            itemSprite = cheesecakeSprite; 
        } 
        if (itemInList == 2) { 
            ItemName = "White Bread"; 
            ItemText = "a basic white loaf that smells amazing"; 
            itemSprite = whitebreadSprite; 
        } 
        if (itemInList == 3) { 
            ItemName = "Cookies"; 
            ItemText = "just plain Chocolatechip cookies, still delishious though"; 
            itemSprite = cookiesSprite; 
        } 
        if (itemInList == 4) { 
            ItemName = "Blueberries"; 
            ItemText = "Big juicy yummy blueberries!"; 
            itemSprite = blueberrySprite; 
            Debug.Log(ItemText); 
        } 
    } 
}

Step 3: Load Data in Your New Scene's Backpack UI

Create a script for your backpack UI in the new scene, and use this to pull data from the manager:

using UnityEngine;
using UnityEngine.UI;

public class BackpackUI : MonoBehaviour
{
    // Assign your backpack slot images in the Inspector
    public Image[] backpackSlots;

    private void Start()
    {
        // Load collected items into the backpack UI
        if (InventoryDataManager.Instance != null)
        {
            for (int i = 0; i < InventoryDataManager.Instance.CollectedItems.Count && i < backpackSlots.Length; i++)
            {
                var item = InventoryDataManager.Instance.CollectedItems[i];
                backpackSlots[i].sprite = item.itemSprite;
                backpackSlots[i].enabled = true; // Make sure the image is visible
            }
        }
    }
}

Key Notes to Avoid Issues:

  • Place all your sprite assets in a Resources folder (or use Addressables for larger projects) to ensure they're accessible across scenes.
  • Double-check that your InventoryDataManager GameObject exists in your initial scene—this is crucial for it to persist through scene loads.
  • You can remove the old gettingID method since we're now storing all necessary data in the manager instead of dynamic GameObjects.

This setup keeps your inventory data alive between scenes, so your backpack sprites will load correctly every time.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:19:05