C# Unity 3d 4.6光线投射忽略精灵上的alpha
所以我有这个,我在上面使用一个脚本来检测拖动事件,这样用户就可以从屏幕的侧面拖动滚动条。问题是,我有一个按钮,坐在上面的粘土印章,它是被封锁的矩形的滚动图片。由于滚动条在移动,我无法准确地将按钮设置为滚动条的父对象。所以我在问是否有办法忽略卷轴上的alpha,让光线投射通过它。我已经有了一个使用方框碰撞器的脚本,并实现了C# Unity 3d 4.6光线投射忽略精灵上的alpha,c#,unity3d,C#,Unity3d,所以我有这个,我在上面使用一个脚本来检测拖动事件,这样用户就可以从屏幕的侧面拖动滚动条。问题是,我有一个按钮,坐在上面的粘土印章,它是被封锁的矩形的滚动图片。由于滚动条在移动,我无法准确地将按钮设置为滚动条的父对象。所以我在问是否有办法忽略卷轴上的alpha,让光线投射通过它。我已经有了一个使用方框碰撞器的脚本,并实现了ICanvasRaycastFilter,但由于某些原因,它似乎无法与unity scroll rect一起工作。以下是完整的脚本: using UnityEngine; usi
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事件。问题在于,滚动条的矩形阻止光线投射到其下方的按钮。长话短说,我通过重新安排场景中的内容,使它们不会相互阻塞,从而在没有花哨代码的情况下修复了它。你的答案也不是真正的答案。