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

Unity C#:当另一列表对象销毁时修改指定列表项标签的问题

How to Update Widget Tags When Corresponding Items Are Destroyed in Unity

Hey Chris, awesome work taking initiative to fix that incomplete code—3 weeks in and you’re already troubleshooting? That’s exactly how you’ll grow fast with Unity and C#! Let’s break down a solid way to make this work.

First, the core issue right now is that your WidgetList and ItemList are separate collections with no clear link between each widget and its corresponding item. We need to establish that connection first, then trigger the tag update when an item gets destroyed. Here are two straightforward approaches tailored for your experience level:

This method adds a reference to the item’s Collider2D directly in your Widget class, making it easy to match them up later.

Step 1: Update Your Widget Class

Add a public field to store the linked item’s collider, and maybe a field for the target tag you want to set:

public class Widget : MonoBehaviour
{
    // Assign this in the Inspector or via code to link to the corresponding item
    public Collider2D linkedItemCollider;
    // Set this to the tag you want to apply when the item is destroyed
    public string tagToSet = "InactiveWidget";
}

Step 2: Add an OnDestroy() Method to Your Item Script

Create a simple script for your items (attach this to every object in ItemList) that checks for its linked widget when it’s destroyed:

public class CollectibleItem : MonoBehaviour
{
    private void OnDestroy()
    {
        // Grab a reference to your manager script that holds WidgetList
        // Replace "WidgetManager" with the name of your actual manager class
        WidgetManager manager = FindObjectOfType<WidgetManager>();
        
        if (manager == null) return; // Exit if we can't find the manager
        
        // Loop through the WidgetList to find the matching widget
        foreach (Widget widget in manager.WidgetList)
        {
            if (widget.linkedItemCollider == GetComponent<Collider2D>())
            {
                // Update the widget's tag
                widget.gameObject.tag = widget.tagToSet;
                break; // No need to keep looping once we find the match
            }
        }
    }
}

Either assign the linkedItemCollider field in the Unity Inspector for each widget, or add code to your manager’s Start() method to auto-link them (if your lists are ordered the same way):

// In your WidgetManager class
private void Start()
{
    // Make sure both lists have the same number of items first!
    if (WidgetList.Count != ItemList.Count)
    {
        Debug.LogError("WidgetList and ItemList don't have matching counts!");
        return;
    }
    
    for (int i = 0; i < WidgetList.Count; i++)
    {
        WidgetList[i].linkedItemCollider = ItemList[i];
    }
}

Approach 2: Use a Dictionary for Faster Lookups (Better for Large Lists)

If you expect to have lots of widgets/items, a Dictionary<Collider2D, Widget> will let you find the matching widget instantly instead of looping through the whole list.

Step 1: Add the Dictionary to Your Manager

Update your manager script to include the dictionary and populate it on start:

public class WidgetManager : MonoBehaviour
{
    private List<Widget> WidgetList = new List<Widget>();
    private List<Collider2D> ItemList = new List<Collider2D>();
    private Collider2D itemSpot;
    // New dictionary to map items to their widgets
    private Dictionary<Collider2D, Widget> ItemToWidgetMap = new Dictionary<Collider2D, Widget>();

    private void Start()
    {
        // Populate the dictionary (again, assume lists are ordered correctly)
        for (int i = 0; i < Mathf.Min(WidgetList.Count, ItemList.Count); i++)
        {
            if (!ItemToWidgetMap.ContainsKey(ItemList[i]))
            {
                ItemToWidgetMap.Add(ItemList[i], WidgetList[i]);
            }
        }
    }
}

Step 2: Update the Item’s OnDestroy() Method

Now we can use the dictionary for instant lookups:

public class CollectibleItem : MonoBehaviour
{
    private void OnDestroy()
    {
        WidgetManager manager = FindObjectOfType<WidgetManager>();
        if (manager == null) return;

        Collider2D myCollider = GetComponent<Collider2D>();
        // Try to get the linked widget from the dictionary
        if (manager.ItemToWidgetMap.TryGetValue(myCollider, out Widget linkedWidget))
        {
            linkedWidget.gameObject.tag = "InactiveWidget";
            // Clean up the dictionary and lists to avoid stale references
            manager.ItemToWidgetMap.Remove(myCollider);
            manager.WidgetList.Remove(linkedWidget);
            manager.ItemList.Remove(myCollider);
        }
    }
}

Quick Notes for Your Workflow

  • Stale References: When items/widgets are destroyed, remember to remove them from your lists/dictionary to avoid errors later.
  • Testing: Add Debug.Log() statements to verify the tag is updating, like Debug.Log($"Updated widget tag to {widget.tagToSet}"); in the OnDestroy method.
  • Alternative: If you don’t want to use OnDestroy(), you can also check for destroyed items in your manager’s Update() method (but OnDestroy() is more efficient).

Hope this gets your code up and running smoothly—keep experimenting, you’re doing great!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:37:25