【问题标题】:Detecting an object with Raycast2D使用 Raycast2D 检测物体
【发布时间】:2018-05-04 11:47:39
【问题描述】:

我正在研究简单的策略游戏机制。我有一个兵营预制件。当我在场景中添加兵营并单击兵营时,收到NullReferenceException 错误:

NullReferenceException:对象引用未设置为对象 PlacementController.Update () 的实例(在 Assets/Scripts/PlacementController.cs:64)

当我尝试使用 Raycast2D 到达军营的对撞机名称时收到错误。

Barracks 预制件有一个 Box Collider2D 碰撞器(已选中触发器),其标签为“Building”,其层为“Buildings”。它有一个rigidbody2D 组件,它是一个运动学刚体。

我无法弄清楚这个问题。请帮帮我。

感谢您的宝贵时间。

using UnityEngine;
using System.Collections;

public class PlacementController : MonoBehaviour
{
    private Buildings buildings;
    private Transform currentBuilding;
    private bool _hasPlaced;
    public LayerMask BuildingsMask;
    public void SelectBuilding(GameObject g)
    {
        _hasPlaced = false;
        currentBuilding = ((GameObject)Instantiate(g)).transform;
        buildings = currentBuilding.GetComponent<Buildings>();
    }

bool CheckPosition()
{
    if (buildings.CollidersList.Count > 0)
    {
        return false;
    }
    return true;
}

// Update is called once per frame
void Update () {


    Vector3 m = Input.mousePosition;
    m = new Vector3(m.x, m.y, transform.position.z);
    Vector3 p = GetComponent<Camera>().ScreenToWorldPoint(m);


    if (currentBuilding != null && !_hasPlaced)
    {

        currentBuilding.position = new Vector3(p.x,p.y,0);

        if (Input.GetMouseButtonDown(0))
        {
            if (CheckPosition())
            {
                _hasPlaced = true;
            }
        }
    }
    else
    {
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit2D hit = new RaycastHit2D();
            Ray2D ray2D = new Ray2D(new Vector2(p.x,p.y), Vector3.down );
            //Ray2D ray = new Ray(transform.position,new Vector3(p.x,p.y,p.z));
            if (Physics2D.Raycast(new Vector2(p.x,p.y),Vector3.down,5.0f,BuildingsMask) )
            {
                Debug.Log(hit.collider.name); //error
            }
        }
    }

}

-----------------我正在分享答案,感谢您的帮助------------------ -

 if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
        {
            RaycastHit2D hit = new RaycastHit2D();
            Ray2D ray2D = new Ray2D(new Vector2(p.x,p.y), Vector3.down );
            hit = Physics2D.Raycast(new Vector2(p.x, p.y), Vector3.forward, 5.0f, BuildingsMask);

                Debug.Log(hit.collider.name);

        }

【问题讨论】:

    标签: unity3d raycasting


    【解决方案1】:

    Unity 有两个物理引擎,它们非常相似,但在一个领域它们以一种微妙而令人困惑的方式不同。

    3D 引擎提供Physics.Raycast,它在命中时返回true,否则返回false,如果您需要了解有关命中的更多信息,则允许您通过引用传递RaycastHit

    2D 引擎提供Physics2D.Raycast,它在命中时返回RaycastHit2D,否则返回null。根据您的代码编写方式,您访问的 hit 与 raycast 调用返回的命中不同。

    所以,你需要更接近这个的东西:

    RaycastHit2D hit = Physics2D.Raycast(...); //edit in your raycast settings
    if (hit) {
        //do something with the hit data
    }
    

    (您可能会注意到RaycastHit2D 隐式转换为bool。)

    Unity 长期以来一直只有 3D 引擎,因此许多旧文档会说得好像只有 3D 引擎一样。请注意这一点。

    【讨论】:

      【解决方案2】:

      使用新的 UI 系统,您不必再像这样手动处理点击。只需在您的 MonoBehaviour 上实现 IPointerClickHandler,并确保场景中存在 EventSystemPhysicsRaycaster

      【讨论】:

        【解决方案3】:

        好的!我检查了所有互联网,但没有人了解人们在谈论 raycast2D 时真正需要什么,我终于找到了他们需要的东西,接受并快乐))我尝试将答案发布到任何地方,以便人们在需要时可以轻松找到它。 从相机屏幕到 2D 精灵,精灵应该与任何对撞机,精灵上的刚体不需要。

        //create 2 empty places for objects
        
        public RaycastHit2D hit;
        public GameObject choosen;
        
        //in update put click on mouse //take Method play by clicking mouse
        
        void Update(){
        if (Input.GetKeyDown (KeyCode.Mouse0)) {
            RayCaster ();
            }
        }
        
        // create raycast Method
        
        void RayCaster (){
            RaycastHit2D ray = Physics2D.GetRayIntersection(Camera.main.ScreenPointToRay (Input.mousePosition));//making ray and object, taking mouse position on screen from camera
            if(!UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject (-1)) {
                if (ray.collider != null) {// for non error, check maybe you hit none collider sprite
                    hit = ray;// not hit is our obj from scene, but we cant work with it as an object
                    choosen = hit.transform.gameObject;// making hit obj as normal object, now we can work with it like with 3Dobject, not as sprite
                }
            }
        }
        

        然后使用选择的 obj。

        把脚本放在相机上,现在每个人都会很高兴,因为在互联网甚至unity3D社区都不明白人们对raycast2D的真正需求,希望将来他们会让这个功能更容易))

        【讨论】:

          【解决方案4】:

          感谢@анонимно,你的回答对我来说非常有效,我只需要用 mousePosition 击中一条射线,并知道这个位置是否被一些 2D 游戏对象(例如精灵)击中。

          我在 OnMouseUp() 方法中调用此点击。

          void OnMouseUp(){
              RaycastHit2D ray = Physics2D.GetRayIntersection(Camera.main.ScreenPointToRay(Input.mousePosition));
          
              if (ray)
              {
                  GameObject hittedGameObject = ray.collider.gameObject;
          
                  // Do something else
          
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2013-12-15
            • 2011-08-06
            • 1970-01-01
            • 2021-04-27
            • 1970-01-01
            • 2021-03-01
            • 1970-01-01
            • 2018-11-18
            相关资源
            最近更新 更多