本文主要是介绍Unity3D在2D游戏中获取触屏物体的方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
我们的需求是:
假如屏幕中一个棋盘,每个棋子是button构成的,我们希望手指或者鼠标在哪里,就显示那个位置的button信息。
网上有很多获取触屏物体信息的信息的方法如下面代码所示:
Camera cam = Camera.main; // pre-defined
...if (touch.phase == TouchPhase.Bagan)){ // 如果触控点状态为按下Ray ray = cam.ScreenPointToRay(Input.position);RaycastHit hit;if (Physics.Raycast(ray, out hit)){Debug.Log(hit.transform.name); // 输出点击物体名称startTouchPos = touch.position;}
}
但是在实际测试时,发现可以进入到if (touch.phase == TouchPhase.Bagan))这个分支中,但是Physics.Raycast(ray, out hit)始终返回false。
错误1:Physics.Raycast方法只适用于3D场景
翻阅资料发现:Physics.Raycast方法适用于3D场景下,在2D场景下是不会起作用的。
于是我们找到了2D场景下的替代方法:Physics2D.Raycast()
该方法最简单的定义如下:
public static RaycastHit2D Raycast(Vector2 origin, Vector2 direction)
需要传入两个参数:origin是射线发射的起始位置,direction是射线的方向。
为了测试效果,我们制作了demo如下:
RayHandler对象对应的脚本RayHandler.cs如下:
public class RayHandler : MonoBehaviour
{// Start is called before the first frame updateprivate Camera _camera;void Start(){_camera = Camera.main; }// Update is called once per framevoid Update(){Vector2 direction = Input.mousePosition - Camera.main.transform.position;RaycastHit2D hit = Physics2D.Raycast(Camera.main.transform.position, direction);Debug.DrawRay(Camera.main.transform.position, direction, Color.red, 30f);if (hit.collider != null){Debug.Log("true");}}
}
加入Debug.DrawRay(Camera.main.transform.position, direction, Color.red, 30f);是为了更方便地观察到射线的情况。
我们发现射线(红色线段)穿透button的次数大大多于true日志的次数。
这个方案还有个缺陷:如果从一个点发出射线,当出发点和终点之间有其他物体时,射线检测到的是另一个物体,而不是当前鼠标(触屏点)对应的物体。
错误2:普通UI如Image、Button等一般用射线是不起作用的。
EventSystem.current.RaycastAll()可以将当前屏幕上的所有可检测的物体全部检测到,该方法需要自己构造一个PointerEventData参数传入检测的点坐标。
参考代码如下:
void Update(){PointerEventData pointerData = new PointerEventData(EventSystem.current);pointerData.position = Input.mousePosition;List<RaycastResult> results = new List<RaycastResult>();EventSystem.current.RaycastAll(pointerData, results);if (results.Count > 0) {foreach (RaycastResult r in results) {if (r.gameObject.layer == LayerMask.NameToLayer("button")) {Debug.Log(r.gameObject.name);}}}}
针对Button1和Button2添加了button的layer,这样就可以过滤出我们想要的物体。
另外我做了测试,创建了Empty、2D Object,使用Physics2D.RaycastAll也没有生效。
测试的代码如下:
void Update(){Vector3 pos = GetTouchPosition();Ray myRay = Camera.main.ScreenPointToRay(pos);RaycastHit2D[] hits = Physics2D.RaycastAll(new Vector2(myRay.origin.x, myRay.origin.y), Vector2.zero);if(hits.Length > 0){Debug.Log("true");}}public static Vector3 GetTouchPosition(){return Input.mousePosition;}
可能Physics2D.RaycastAll适用于一个游戏Player向另一个物体发射射线,而不是从触屏点发射射线。反正从触屏点通过Physics.Raycast类函数发射射线我始终没有成功过!!!!
这篇关于Unity3D在2D游戏中获取触屏物体的方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!