Unity - C# 当一个列表中的对象被销毁时,尝试更改另一个列表中的项的标记



最近参加了一个关于初学者 c# w/unity 的在线课程,不幸的是,讲师以损坏和未完成的代码结束了课程。 拥有大约 3 周的经验,我决定在继续之前学习、研究并制作一个可行的构建。

我有两个列表和一个变量:

private List<Widget> WidgetList = new List<Widget>();
private List<Collider2D> ItemList = new List<Collider2D>();
private Collider2D itemSpot;

然后,我在更新方法中有一个 if 语句,单击鼠标左键后,代码会更改所单击项目的标签,将该项目添加到ItemList,并在该位置生成一个新的小部件。

if (Input.GetMouseButtonDown (0)) {
Vector2 worldPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast (worldPoint, Vector2.zero);
if (hit.collider.tag == "BlankItem") {
itemSpot = hit.collider;
itemSpot.tag = "FullItem";
RegisterItemSpot (itemSpot);
MakeWidget (hit);
}
}

这目前工作正常,尽管我的印象不是最理想的代码(不是一个制作精良的课程(。 对RegisterItemSpotMakeWidget方法的调用完美运行,每个方法都正确使用 .添加到各自的列表中。 在游戏结束时,我有一种方法可以毫无问题地清除两个列表。

这是我的障碍:如果我销毁小部件的单个实例,我希望与之关联的itemSpot再次将其标签更改为"BlankItem"。 我使用了与之前类似的函数来销毁小部件:

void Update (){
if (Input.GetMouseButtonDown (0)) {
Vector2 worldPointt = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hitt = Physics2D.Raycast (worldPointt, Vector2.zero);
if (hitt.collider.tag == "Tower" && destroyMode != false)
Destroy(hitt.transform.gameObject);
}
}

从那里在 Widget 类的OnDestroy中,我让它从列表中删除自己,这也很好用。

在我的脑海中,我想象了几行代码,在小部件的OnDestroy内,将重命名最初与该特定销毁的 Widget 关联的itemSpot。我不知道如何将新小部件与特定itemSpot相关联。 类似于"如果这个对象被摧毁,那么与该碰撞机相关的对象将被重新标记"之类的东西。我的一些想法需要从头开始重建这段代码(也许是制作数组而不是列表?我觉得我的新手大脑会更好地继续我的下一个课程,而不是花那么多时间。 也许不是? 我只需要一些更有经验的人的建议。 如果我需要提供更多信息,请告诉我(10 类数百代码似乎太多了,不能在这里扔(。

编辑:我包括MakeWidget((方法和RegisterItemSpot((和RegisterWidget((方法。 我应该从一开始就有,非常抱歉!

public void MakeWidget (RaycastHit2D hit){
if (!EventSystem.current.IsPointerOverGameObject) {
Tower newWidget = Instantiate (widgetBtnPressed.WidgetObject);
newWidget.transform.position = hit.transform.position;
RegisterWidget (newWidget);
widgetBtnPressed = null;}
}
public void RegisterItemSpot (Collider2D itemSpot){
ItemList.Add(itemSpot);
}
public void RegisterWidget (Widget widget)
{
WidgetList.Add(widget);
}

我认为你最好的方法是创建一个新的容器类,然后声明一个该类的新列表。这是一个例子

public class WidgetContainer()
{
public Widget widget;
public Collider2D collider;
}

然后用这个列表替换你的两个列表

public List<WidgetContainer> widgetContainers = new List<WidgetContainer>();

然后将您的makewidget和registeritemspot方法合并为一个方法,并创建一个新的WidgetContainer并将其添加到列表中。现在,您将始终在这两个变量之间存储连接。

var newContainer = new WidgetContainer
{
widget = newWidget,
collider = itemSpot
}

最后,在您所描述的所述小部件的OnDestroy((中,您可以这样做:

widgetContainers.First(x => x == this).collider.tag = "your tag here";

"this"引用类的实例。在您的情况下,这将是您的小部件脚本。

不要这样说,您需要在 Linq 脚本的顶部添加此 using 语句。

using System.Linq;

最新更新