在Unity中检查触摸点是否在盒形碰撞器内。

7
请查看以下图片:

在这里输入图片描述

在这里输入图片描述

第一张图片显示了一个盒子碰撞器。
第二张图片是我在Android设备上运行代码时的效果。
以下是附加到Play Game(它是一段3D文本)的代码。
using UnityEngine;
using System.Collections;

public class PlayButton : MonoBehaviour {   

    public string levelToLoad;
    public AudioClip soundhover ;
    public AudioClip beep;
    public bool QuitButton;
    public Transform mButton;
    BoxCollider boxCollider;

    void Start () {
        boxCollider = mButton.collider as  BoxCollider;
    }

    void Update () {

        foreach (Touch touch in Input.touches) {

            if (touch.phase == TouchPhase.Began) {

                if (boxCollider.bounds.Contains (touch.position)) {
                    Application.LoadLevel (levelToLoad);
                }
            }                
        }
    }
}

我希望确定触摸点是否在碰撞器内。我想这样做是因为当前情况是,如果我在场景上点击任何位置,则调用Application.LoadLevel(levelToLoad)。

我希望只有当我点击PLAY GAME文本时才调用它。有人能帮我修复这段代码或提供另一种解决方案吗?


根据Heisenbug的逻辑进行的最近代码

void Update () {

foreach( Touch touch in Input.touches ) {

    if( touch.phase == TouchPhase.Began ) {

        Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, Mathf.Infinity, 10)) {
            Application.LoadLevel(levelToLoad);             
        }           
    }   
}
}
1个回答

8

触摸的位置是以屏幕空间坐标系(一个 Vector2)表示的。在尝试将其与场景中其他 3D 物体的位置进行比较之前,您需要将该位置转换为世界空间坐标系。

Unity3D 提供了这样的功能。由于您正在使用包围文本的 BoundingBox,因此可以执行以下操作:

  • 创建一个光线(Ray),其起点位于触摸点位置,方向平行于相机前向轴(Camera.ScreenPointToRay)。
  • 检查该光线是否与您的 GameObjectBoundingBox 相交(Physic.RayCast)。

代码可能类似于以下内容:

Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerOfYourGameObject))
{
   //enter here if the object has been hit. The first hit object belongin to the layer "layerOfYourGameObject" is returned.
}

为了让射线与特定的“Play Game”GameObject碰撞,方便地将一个特定的层添加到它上面。


编辑

上面的代码和解释是正确的。如果您没有得到正常的碰撞,可能是您没有使用正确的图层。我目前没有触摸设备。以下代码将与鼠标一起使用(不使用图层)。

using UnityEngine;
using System.Collections;

public class TestRay : MonoBehaviour {

    void Update () {

        if (Input.GetMouseButton(0))
        {
            Vector3 pos = Input.mousePosition;
            Debug.Log("Mouse pressed " + pos);

            Ray ray = Camera.mainCamera.ScreenPointToRay(pos);
            if(Physics.Raycast(ray))
            {
                Debug.Log("Something hit");
            }

        }
    }

}

这只是一个示例,为了帮助你找到正确的方向。尝试弄清楚在你的情况下出了什么问题,或者发布一个SSCCE


我所做的是,选择了3D文本,并在检查器中将其分配到图层。图层编号为8。之后,我将参数layerOfYourGameObject设置为8并运行了代码,但仍然没有发生碰撞。我已经在上面的问题中附上了代码。 - Jawad Amjad
如果我在添加3D文本层方面有误,请纠正我。 1)选择3D文本。 2)在检查器中转到AddLayer并将Unity Layer 10命名为PlayGameLayer。 3)在检查器中标记=未标记和层= PlayGameLayer。 4)具有上述代码的脚本附加到PlayGame 3d Text。 这是正确的方法吗?如果是,那么可能出了什么问题? - Jawad Amjad
@Jawad Amjad:你是否将边界框附加到了已经附加了Text组件的同一GameObject上? - Heisenbug
是的,我已经将它附加到3D文本上。 - Jawad Amjad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接