Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity 3d 4.6光线投射忽略精灵上的alpha_C#_Unity3d - Fatal编程技术网

C# Unity 3d 4.6光线投射忽略精灵上的alpha

C# Unity 3d 4.6光线投射忽略精灵上的alpha,c#,unity3d,C#,Unity3d,所以我有这个,我在上面使用一个脚本来检测拖动事件,这样用户就可以从屏幕的侧面拖动滚动条。问题是,我有一个按钮,坐在上面的粘土印章,它是被封锁的矩形的滚动图片。由于滚动条在移动,我无法准确地将按钮设置为滚动条的父对象。所以我在问是否有办法忽略卷轴上的alpha,让光线投射通过它。我已经有了一个使用方框碰撞器的脚本,并实现了ICanvasRaycastFilter,但由于某些原因,它似乎无法与unity scroll rect一起工作。以下是完整的脚本: using UnityEngine; usi

所以我有这个,我在上面使用一个脚本来检测拖动事件,这样用户就可以从屏幕的侧面拖动滚动条。问题是,我有一个按钮,坐在上面的粘土印章,它是被封锁的矩形的滚动图片。由于滚动条在移动,我无法准确地将按钮设置为滚动条的父对象。所以我在问是否有办法忽略卷轴上的alpha,让光线投射通过它。我已经有了一个使用方框碰撞器的脚本,并实现了
ICanvasRaycastFilter
,但由于某些原因,它似乎无法与unity scroll rect一起工作。以下是完整的脚本:

using UnityEngine;
using System.Collections;

public class RaycastFilter : MonoBehaviour, ICanvasRaycastFilter
{
    private RectTransform rectTransform;
    private new BoxCollider2D collider2D;

    public void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
        collider2D = GetComponent<BoxCollider2D>();
    }

    public bool IsRaycastLocationValid(Vector2 screenPosition, Camera raycastEventCamera) //uGUI callback
    {
        // If we don't have a collider we will simply use the big button box. //TODO: make custom exception for this.
        if (collider2D == null)
            return true;

        Vector2 localPoint;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPosition, raycastEventCamera, out localPoint);

        Vector2 pivot = rectTransform.pivot - new Vector2(0.5f, 0.5f);

        Vector2 pivotScaled = Vector2.Scale(rectTransform.rect.size, pivot);

        Vector2 realPoint = localPoint + pivotScaled;

        Rect colliderRect = new Rect(
            collider2D.center.x - collider2D.size.x / 2,
            collider2D.center.y - collider2D.size.y / 2,
            collider2D.size.x,
            collider2D.size.y); // TODO: CACHE

        bool containsRect = colliderRect.Contains(realPoint);

        return containsRect;
    }
}
使用UnityEngine;
使用系统集合;
公共类RaycastFilter:MonoBehavior,ICanvasRaycastFilter
{
私有矩形变换;
私人新BoxCollide R2D Collide R2D;
公共图书馆
{
rectTransform=GetComponent();
collider2D=GetComponent();
}
公共布尔值IsRaycastLocationValid(矢量2屏幕位置,摄影机光线投射虚拟摄像机)//uGUI回调
{
//如果我们没有对撞机,我们只需使用大按钮盒。//TODO:对此进行自定义例外。
如果(r2d==null)
返回true;
向量2局部点;
ScreenPointToLocalPointInRectangle(rectTransform、screenPosition、raycastEventCamera、out localPoint);
Vector2 pivot=rectTransform.pivot-新Vector2(0.5f,0.5f);
Vector2 pivotScaled=Vector2.Scale(rectTransform.rect.size,pivot);
Vector2 realPoint=localPoint+pivotScaled;
Rect colliderRect=新的Rect(
碰撞r2d.center.x-碰撞r2d.size.x/2,
碰撞r2d.center.y-碰撞r2d.size.y/2,
碰撞r2d.size.x,
冲突的r2d.size.y);//TODO:缓存
bool containsRect=colliderRect.Contains(realPoint);
退回集装箱;
}
}

您正在使用ScrollRect组件吗?如果没有,你将真的有很多问题,ScrollRect来自新的用户界面,你不必编码输入触摸,它会自动为你提供一个完美的输入识别

您也可以向ScrollRect添加滑块。我建议你看这个视频


将滑块组件也添加到ScrollRect中,这样您就可以自定义一个“无需担心光线投射忽略”的滑块。

如果有人像我一样偶然发现了这一点,下面是我在3D世界中通过alpha进行光线投射精灵的解决方案

首先,使用逆变换将你的生命点变换到精灵的局部空间。然后,添加精灵的轴心点。因为它是以像素表示的,所以将其除以每单位的像素可以得到正确的偏移量。 要获取该局部点的UV值,请将其除以精灵边界大小。这将为您提供介于0和1之间的值。因为我们的坐标系是Y向上,纹理是Y向下,所以我们必须反转Y值。 现在很容易读取正确的像素。将UV与纹理宽度和高度相乘

    private GameObject Raycast(Vector2 screenPos)
    {
        Ray ray = new Ray(_camera.ScreenToWorldPoint(screenPos), _camera.transform.forward);

        var result = Physics.RaycastAll(ray, float.MaxValue).ToList().OrderByDescending(h => h.distance); //inverse raycast

        foreach (var hit in result)
        {
            var rend = hit.transform.GetComponent<SpriteRenderer>();
            if (rend == null)
                continue;

            Vector2 localPos = hit.transform.InverseTransformPoint(hit.point);
            localPos += rend.sprite.pivot / rend.sprite.pixelsPerUnit;

            Vector2 uv = localPos / rend.sprite.bounds.size;
            uv.y = 1f - uv.y;

            Texture2D tex = rend.sprite.texture as Texture2D;

            int x = (int)(uv.x * tex.width);
            int y = (int)(uv.y * tex.height);
            var pix = tex.GetPixel(x, y);

            if (pix.a > 0)
            {
                return hit.transform.gameObject;
            }
        }

        return null;
    }
私人游戏对象光线投射(Vector2屏幕位置)
{
光线=新光线(_camera.ScreenToWorldPoint(screenPos),_camera.transform.forward);
var result=Physics.RaycastAll(ray,float.MaxValue).ToList().OrderByDescending(h=>h.distance);//反向光线投射
foreach(var命中结果)
{
var rend=hit.transform.GetComponent();
如果(rend==null)
继续;
Vector2 localPos=hit.transform.InverseTransformPoint(hit.point);
localPos+=rend.sprite.pivot/rend.sprite.pixelsPerUnit;
Vector2UV=localPos/rend.sprite.bounds.size;
uv.y=1f-uv.y;
Texture2D tex=rend.sprite.texture作为Texture2D;
int x=(int)(uv.x*tex.width);
int y=(int)(uv.y*tex.height);
var pix=tex.GetPixel(x,y);
如果(pix.a>0)
{
返回hit.transform.gameObject;
}
}
返回null;
}

我使用的是ScrollRect,我不需要滑块,因为我使用的是DragOn和PointerUp事件。问题在于,滚动条的矩形阻止光线投射到其下方的按钮。长话短说,我通过重新安排场景中的内容,使它们不会相互阻塞,从而在没有花哨代码的情况下修复了它。你的答案也不是真正的答案。