OnMouseDown() 只调用最重要的 GameObject
OnMouseDown() called for only the foremost GameObject
(来源:ibin.co)
我有一个 BoxCollider2D 组件和一个附加到黑色和红色框的脚本。每个脚本都会在 OnMouseDown() 函数中发生一些事情。问题是,如果我点击橙色框与黑色框重叠的部分,黑色框的 OnMouseDown() 将被调用,但我只想调用橙色框函数。
你是如何做到这一点的?
我不认为 OnMouseDown 是一个很好的方法。您可以使用 2D RayCast 只获取最顶层的碰撞器。使用这种方法,您将不得不自己考虑排序层和排序顺序。
检查 2D 中单个点的技巧是不给出如下所示的光线投射方向:
Physics2D.Raycast(touchPostion, Vector2.zero);
这是我拼凑的一个示例,它不考虑使用排序层,只考虑排序顺序。
using UnityEngine;
public class RayCastMultiple : MonoBehaviour
{
//Current active camera
public Camera MainCamera;
// Use this for initialization
void Start ()
{
if(MainCamera == null)
Debug.LogError("No MainCamera");
}
// Update is called once per frame
void FixedUpdate ()
{
if(Input.GetMouseButtonDown(0))
{
var mouseSelection = CheckForObjectUnderMouse();
if(mouseSelection == null)
Debug.Log("nothing selected by mouse");
else
Debug.Log(mouseSelection.gameObject);
}
}
private GameObject CheckForObjectUnderMouse()
{
Vector2 touchPostion = MainCamera.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D[] allCollidersAtTouchPosition = Physics2D.RaycastAll(touchPostion, Vector2.zero);
SpriteRenderer closest = null; //Cache closest sprite reneder so we can assess sorting order
foreach(RaycastHit2D hit in allCollidersAtTouchPosition)
{
if(closest == null) // if there is no closest assigned, this must be the closest
{
closest = hit.collider.gameObject.GetComponent<SpriteRenderer>();
continue;
}
var hitSprite = hit.collider.gameObject.GetComponent<SpriteRenderer>();
if(hitSprite == null)
continue; //If the object has no sprite go on to the next hitobject
if(hitSprite.sortingOrder > closest.sortingOrder)
closest = hitSprite;
}
return closest != null ? closest.gameObject : null;
}
}
这几乎只是我在这里的回答的重复:Game Dev Question
(来源:ibin.co)
我有一个 BoxCollider2D 组件和一个附加到黑色和红色框的脚本。每个脚本都会在 OnMouseDown() 函数中发生一些事情。问题是,如果我点击橙色框与黑色框重叠的部分,黑色框的 OnMouseDown() 将被调用,但我只想调用橙色框函数。
你是如何做到这一点的?
我不认为 OnMouseDown 是一个很好的方法。您可以使用 2D RayCast 只获取最顶层的碰撞器。使用这种方法,您将不得不自己考虑排序层和排序顺序。
检查 2D 中单个点的技巧是不给出如下所示的光线投射方向:
Physics2D.Raycast(touchPostion, Vector2.zero);
这是我拼凑的一个示例,它不考虑使用排序层,只考虑排序顺序。
using UnityEngine;
public class RayCastMultiple : MonoBehaviour
{
//Current active camera
public Camera MainCamera;
// Use this for initialization
void Start ()
{
if(MainCamera == null)
Debug.LogError("No MainCamera");
}
// Update is called once per frame
void FixedUpdate ()
{
if(Input.GetMouseButtonDown(0))
{
var mouseSelection = CheckForObjectUnderMouse();
if(mouseSelection == null)
Debug.Log("nothing selected by mouse");
else
Debug.Log(mouseSelection.gameObject);
}
}
private GameObject CheckForObjectUnderMouse()
{
Vector2 touchPostion = MainCamera.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D[] allCollidersAtTouchPosition = Physics2D.RaycastAll(touchPostion, Vector2.zero);
SpriteRenderer closest = null; //Cache closest sprite reneder so we can assess sorting order
foreach(RaycastHit2D hit in allCollidersAtTouchPosition)
{
if(closest == null) // if there is no closest assigned, this must be the closest
{
closest = hit.collider.gameObject.GetComponent<SpriteRenderer>();
continue;
}
var hitSprite = hit.collider.gameObject.GetComponent<SpriteRenderer>();
if(hitSprite == null)
continue; //If the object has no sprite go on to the next hitobject
if(hitSprite.sortingOrder > closest.sortingOrder)
closest = hitSprite;
}
return closest != null ? closest.gameObject : null;
}
}
这几乎只是我在这里的回答的重复:Game Dev Question