c# - Unity - C#试图在另一个列表中的对象被销毁时更改一个列表中的项目的标签
问题描述
最近参加了一个关于初学者 c# w/unity 的在线课程,不幸的是,讲师以一个损坏且未完成的代码结束了课程。有了大约 3 周的经验,我决定在继续之前学习、研究并做出可行的构建。
我有两个列表和一个变量:
private List<Widget> WidgetList = new List<Widget>();
private List<Collider2D> ItemList = new List<Collider2D>();
private Collider2D itemSpot;
然后,我在 update 方法中有一个 if 语句,单击鼠标左键后,代码会更改所单击项目的标签,将该项目添加到 a ItemList
,并在该位置生成一个新的 Widget。
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);
}
}
这目前工作正常,尽管我觉得它不是最理想的代码(不是一个制作精良的课程)。对RegisterItemSpot
和MakeWidget
方法的调用完美无缺,每个都正确使用 .Add 到各自的列表中。在游戏结束时,我有一个方法可以毫无问题地清除两个列表。
这是我的障碍:如果我销毁 Widget 的单个实例,我希望与之关联的 itemSpot"BlankItem"
再次将其标记更改为。我使用了与之前类似的函数来销毁 Widget:
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);
}
}
从那里在OnDestroy
Widget 类中,我将其从列表中删除,这也很好。
在我的脑海中,我想象有几行代码,在OnDestroy
Widget 中,将重命名itemSpot
最初与该特定已销毁 Widget 相关联的 。我不知道如何将新的 Widget 与特定的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”引用类的实例。在您的情况下,这将是您的 Widgetscript。
不要认为您需要在 Linq 脚本的顶部添加此 using 语句。
using System.Linq;
推荐阅读
- php - 使用正则表达式 PHP 将文本文件拆分为数组
- html - 如何阻止Angular 9跳过附加了Js函数的span元素?
- spring-cloud - Spring Cloud Zuul - 在路由之前向传入请求添加 http 代理详细信息(代理服务器、代理端口、凭据等)
- python - 如何为 GTK/LibHandy 片段修复 Gtk.ListBox 中的大丑开关按钮
- firebase - Firebase 中的多个站点部署问题
- amazon-web-services - AWS Backup:缺少权限 iam:PassRole
- c++ - 如何对移动操作进行单元测试(默认)?
- groovy - AEM 6.5,使用 Groovy 脚本创建批量页面
- go - 有没有一种好方法来更新传递给 Golang 中子测试的结构
- shell - 在 shell 脚本中提取 json 有效负载