在raycast 2D处销毁对象会导致无关对象被破坏

时间:2017-01-09 03:45:04

标签: c# unity3d mouseover instantiation destroy

在我的游戏中,用户可以通过鼠标点击产生2个预制件的实例化版本:瓷砖和球。球可以在瓷砖上产生。

用户还可以擦除已生成的对象。这是通过将以下代码放在更新方法的if(Input.GetMouseButtonDown(0)))块中来实现的:

if (Input.GetMouseButtonDown(0))
{
    Vector3 mousePos = Input.mousePosition;
    mousePos.z = canvas.transform.position.z;
    Vector3 mousePosTrans = Camera.main.ScreenToWorldPoint(mousePos);
    RaycastHit2D rayHit = Physics2D.Raycast(mousePosTrans, Vector2.zero);
    if (eraserSelected)
    {
        Destroy(rayHit.collider.gameObject);
    }
}

正在删除要删除的对象,但问题是其他无关和远程对象有时也会同时删除。例如,如果我在每个方格上产生2个方格和一个球,则删除第一个球,当我去删除第一个方格时,同时删除第二个球。有时当一个对象被删除时,另一个对象同时被“删除”!

使用以下代码生成对象:

TileOrBall obj = (TileOrBall) Instantiate(tileOrBall, pos, Quaternion.identity);
obj.transform.SetParent(canvas.transform);

其中TileOrBall是要生成的对象的类,tileOrBall是对此类中两个预制件之一的引用。

那么我正在采取什么方法来对抗产卵或破坏呢?在尝试销毁这些对象的实例时,如何解决不同对象的同时删除(有时是复活)?

修改

添加项目zip文件的链接:

https://drive.google.com/open?id=0B28_MgFRWv97OWxfNE96LXcxZHc

要复制此问题,请单击侧栏中的方块,然后在网格中“绘制”方块,然后单击侧栏中的球并“涂抹”已放置的方块。最后,单击橡皮擦图标并通过单击它们开始删除对象。您将看到未删除的对象被删除,当您尝试删除对象时,您甚至可能会看到对象被复活。

谢谢!

2 个答案:

答案 0 :(得分:1)

在项目中发现了一些问题。

1 。当您执行Destroy(unitAtMouse);时,您不会从光线播放中删除GameObject。您删除附加到该GameObject的Unit脚本。

由于此删除失败,您将在一个位置中拥有多个 Square GameObjects 。这使得以后删除更加困难,因为您必须多次单击删除,直到删除最后一个 Square GameObjects

要解决此问题,请将Destroy(unitAtMouse);替换为Destroy(unitAtMouse.gameObject);

2 。让您实例化为GameObject而不是脚本的GameObject是件好事。例如,public Unit selectedObject;应为public GameObject selectedObject;

3 。点击侧栏中的方形或圆圈时,将eraserSelected设置为false。这解决了即使用户在eraserSelected模式下再次选择正方形的问题,也可以删除甚至创建新的正方形。如果单击侧栏中的方形或圆形,则要禁用eraserSelected。换句话说,如果调用setSelectedObject

4 。擦除按钮也应该像其他按钮一样位于面板下方。否则,它将在某些屏幕分辨率下丢失。

5 .Fixed枚举使用实际枚举而不是enum.string

6 。修复一个让球看不见的问题,让它看起来像是被删除了。发生的事情是球被送到广场后面。通过将球sortingOrder设为1,将方格sortingOrder设为0来解决此问题。

答案 1 :(得分:0)

或者,根据@ Programmer的回复,您可以创建一个新脚本,比如说DeletableObject,暂时可以完全为空,并将其附加到球和方形预制件以及您可能拥有的任何未来预制件上。然后在上面建议的代码中,更改:

if (rayHit.collider.CompareTag("ball"))

if(rayHit.collider.GetComponent<DeletableObject>())

通过这种方式,您可以将脚本附加到您为了能够删除它们而生成的任何未来预制件。

另外,如果您要添加/删除大量对象并且性能成为问题,请查看Object Pooling。事实上,你应该调查一下,因为这是一个很好的习惯。