理解和使用Unity的Physics2D.OverlapArea()

时间:2015-04-25 12:23:00

标签: c# unity3d game-physics

我正在尝试编写一个脚本,在屏幕上的随机位置实例化一个方形预制件。如果空间已经被先前实例化的方块占用,那么它应该只是在控制台中写一些东西。这是我写的代码:

    public void SpawnSquares(int difficulty){
    float R1=Random.Range(25.0f,_screenWidth);
    float R2=Random.Range(25.0f,_screenHeight);

    _overlapA=new Vector2(R1-50f,R2+50f);
    _overlapB=new Vector2(R1+50f,R2-50f);

    if(Physics2D.OverlapArea(_overlapA,_overlapB,layermask,Mathf.Infinity,Mathf.Infinity)==null){
        _position=Camera.main.GetComponent<Camera>().ScreenToWorldPoint(new Vector3(R1,R2,10));
        Instantiate(Resources.Load("Square",typeof (GameObject)),_position,Quaternion.identity);

    }
    else{
        Debug.Log("avoided collision");
    }
}

将layermask变量设置为layermask = 1&lt;&lt; 9;因为所有的方块都位于第9层。

我期望这样做是生成随机位置并修改_overlapA和_overlapB以考虑方块的大小,然后检查该特定区域中是否有任何碰撞器。如果没有(OverlapArea()== null)那么它应该在该位置产生一个新的正方形。如果空间被占用,只需写入控制台。

实际发生了什么?执行永远不会在else上分支,因此这意味着Physics2D.OverlapArea(_overlapA,_overlapB,layermask,Mathf.Infinity,Mathf.Infinity)始终返回null。然而,在调用SpawnSquares()大约10次之后,屏幕几乎充满了正方形,所以它至少应该检测到一个对撞机。

我做错了什么?我的项目在过去的两天里一直停滞不前,因为我似乎无法解决这个问题,所以任何帮助都会受到高度赞赏。

谢谢你的时间!

1 个答案:

答案 0 :(得分:1)

你有一个逻辑错误,但你显然是在正确的道路上。只是错过了检查的主要概念。

3主要问题。

  1. 您正在检查预先实例化的Physics2d,所以无论发生什么,它都会返回Null;

    if(Physics2D.OverlapArea(_overlapA,_overlapB,layermask,Mathf.Infinity,Mathf.Infinity)==null){
    _position=Camera.main.GetComponent<Camera>().ScreenToWorldPoint(new Vector3(R1,R2,10));
    Instantiate(Resources.Load("Square",typeof (GameObject)),_position,Quaternion.identity);
    
    }
    else{
        Debug.Log("avoided collision");
    }
    
  2. 这里的逻辑说,嘿,检查我的Physics2d。如果我与“MyOwn _overlapA和_overlapB重叠。那么它是实例化的,这将始终返回true。但它尚未实例化,这意味着它总是会给你错误的。

    要解决此问题,您需要告诉它与游戏中存在的“OTHER Physics2d”进行比较。

    示例

    if(Physics2D.OverlapArea(otherphysics2d.overlapA,otherphysics2d.overlapB
    
    1. 现在了解第一个解决方案,会让你思考第二个问题。我怎样才能引用我实例化过的那些?我怎样才能获得他们的Physics2D?
    2. 这是制作清单所需的部分

         // Needs to be out of the Method to be accessible to all.
           public List<GameObject> mySpawns = new List<GameObject>();
      

      现在,在实例化它们之后,将它们添加到列表中。

      if(Physics2D.OverlapArea(_overlapA,_overlapB,layermask,Mathf.Infinity,Mathf.Infinity)==null){
          _position=Camera.main.GetComponent<Camera>().ScreenToWorldPoint(new Vector3(R1,R2,10));
      GameObject newGameObject = Instantiate(Resources.Load("Square",typeof (GameObject)),_position,Quaternion.identity);
          mySpawns.Add(newGameObject);
          }
          else{
              Debug.Log("avoided collision");
          }
      
         // Take note that if you miss a cast for some reason, just add "as GameObject" at the end to DownCast it.
      
      1. 检查部分是如何检查每个列表的。易于使用foreach。

         foreach(GameObject check in mySpawns)
             {
                vector2 MyX = check.Collider2D.transform.x;
                vector2 MyY = check.Collider2D.transform.y;                       if(Physics2D.OverlapArea(MyX,MyY,layermask,Mathf.Infinity,Mathf.Infinity)==null){
        _position=Camera.main.GetComponent<Camera>().ScreenToWorldPoint(new Vector3(R1,R2,10));
              GameObject newGameObject = Instantiate(Resources.Load("Square",typeof (GameObject)),_position,Quaternion.identity);
        mySpawns.Add(newGameObject);
        }
          else   {
               Debug.Log("avoided collision");
           }
        
        }
        
      2. 最后你可以做自己的事。只需在预制件上添加一个Physics2D组件,并确保其中有物理,并确保没有物理因素,因为它适用于3D。

      3. 欢迎使用StockOverflow