【问题标题】:Unity objects not in layermask getting hit by raycast [duplicate]不在图层蒙版中的 Unity 对象被光线投射击中 [重复]
【发布时间】:2017-11-17 00:25:45
【问题描述】:

我正在使用光线投射来检测与可控层上的对象的碰撞。由于某种原因,不在可控层上的对象也会受到影响。这是我调用光线投射的代码。

if (Input.touches.Length > 0)
    {
        RaycastHit hit;
        if (Physics.Raycast(firstPersonCamera.ScreenPointToRay(Input.GetTouch(0).position), out hit, controllableLayer))
        {
            Debug.Log("Object hit");
            Debug.Log(hit.transform.gameObject.name);

            Touch touch = Input.GetTouch(0);

            GameObject objectHit = hit.transform.gameObject;

            if (dragging)
            {
                Vector3 cursorScreenPoint = new Vector3(touch.position.x, touch.position.y, screenPoint.z);
                Vector3 cursorPosition = firstPersonCamera.ScreenToWorldPoint(cursorScreenPoint) + offset;
                objectHit.transform.position = cursorPosition;
            }
            // Handle finger movements based on touch phase.
            switch (touch.phase)
            {
                // Record initial touch position.
                case TouchPhase.Began:
                    screenPoint = firstPersonCamera.WorldToScreenPoint(objectHit.transform.position);
                    offset = objectHit.transform.position - firstPersonCamera.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, screenPoint.z));
                    dragging = true;
                    break;

                // Determine direction by comparing the current touch position with the initial one.
                case TouchPhase.Moved:
                    break;

                // Report that a direction has been chosen when the finger is lifted.
                case TouchPhase.Ended:
                    dragging = false;
                    break;
            }
        }
        else
        {
            Debug.Log("Nothing hit");
        }
    }

这里也是我声明图层蒙版的地方

void Awake()
{
    firstPersonCamera = GameObject.Find("First Person Camera").GetComponent<Camera>();
    controllableLayer = LayerMask.NameToLayer("Controllable");
    Debug.Log(LayerMask.LayerToName(controllableLayer));
}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    由于Layers使用位移,所以在raycasting时你必须这样做:

    int layerMask = 1 << controllableLayer;
    Physics.Raycast(firstPersonCamera.ScreenPointToRay(Input.GetTouch(0).position), out hit, layerMask)
    

    否则,将controllableLayer 声明为整数并执行以下操作:

    int controllableLayer ;
    
    void Awake()
    {
        controllableLayer = 1 << LayerMask.NameToLayer("Controllable");
    }
    
    void Update()
    {
        // ...
        if( Physics.Raycast(firstPersonCamera.ScreenPointToRay(Input.GetTouch(0).position), out hit, controllableLayer) )
        {
            // ...
        }
    }
    

    检查这些链接:

    1. https://answers.unity.com/questions/472886/use-layer-name-for-layermask-instead-of-layer-numb.html
    2. https://gamedev.stackexchange.com/questions/132132/why-do-unity-layer-masks-need-to-use-bit-shifting

    【讨论】:

    • 所以我还需要保持清醒状态吗? controllableLayer = LayerMask.NameToLayer("可控");
    • 是的,或者您可以将controllableLayer 声明为int 并在Awake 中分配其值,如下所示:controllableLayer = 1 &lt;&lt; LayerMask.NameToLayer("Controllable"); 然后,在调用Raycast 时,保留您所拥有的:@ 987654331@(查看我更新的答案)
    • 显然我实际上做错了两件事。我没有像你说的那样做位移,但我也使用了不正确的构造函数。我使用的构造函数将图层蒙版视为最大距离参数。我现在修好了,谢谢你的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多