使用Raycast2D检测对象

时间:2015-04-19 23:55:08

标签: unity3d raycasting

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

  

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

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

军营预制件有一个Box Collider2D对撞机(触发器被检查),其标签是" Building"它的层是#34; Buildings"。它有一个刚体2D组件,它是一个运动刚体。

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

感谢您的时间。

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);

        }

4 个答案:

答案 0 :(得分:6)

Unity有两个物理引擎,它们非常相似,但这是一个区域,它们以微妙和混乱的方式不同。

3D引擎提供Physics.Raycast,在点击时返回true,否则返回false,如果您需要了解更多,则可以通过引用传递RaycastHit关于打击。

2D引擎提供Physics2D.Raycast,而在点击时返回RaycastHit2D,否则返回null。编写代码的方式,您访问的hit与光线投射调用返回的命中不同。

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

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

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

Unity很长一段时间都只有3D引擎,所以很多旧的文档都会说话,好像这是唯一一个。请注意这一点。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

OK!我检查所有互联网,没有人理解人们真正需要什么时,我最终找到他们需要的东西,采取,并快乐))生病尝试回答所有地方,以便人们可以轻松找到它,如果它的需要。 从相机屏幕到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,希望将来可能会让这个功能变得更容易))

答案 3 :(得分:0)

谢谢@анонимно,你的答案对我来说非常有用,我只是需要使用mousePosition打一个光线,并知道这个位置是否与某个2D gameObject匹配,例如精灵。

我在OnMouseUp()方法中调用了这个命中。

void OnMouseUp(){
    RaycastHit2D ray = Physics2D.GetRayIntersection(Camera.main.ScreenPointToRay(Input.mousePosition));

    if (ray)
    {
        GameObject hittedGameObject = ray.collider.gameObject;

        // Do something else

    }
}