所以我有这个image我正在使用它来检测拖动事件,以便用户可以从屏幕一侧拉动滚动。问题是我有一个位于粘土密封上方的按钮,它被滚动图片的矩形阻挡。由于滚动移动我不能完全按下它的按钮。所以我问是否有办法忽略滚动上的alpha并让光线投射通过它。我已经有一个使用盒式对撞机的脚本并实现了ICanvasRaycastFilter
,但由于某些原因它似乎不能使用统一滚动矩形。这是完整的脚本:
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;
}
}
答案 0 :(得分:1)
万一有人像我一样偶然发现这个问题,这是我在3D世界中通过alpha射线投射精灵的解决方案。
首先,使用逆变换将击中点转换为精灵的局部空间。然后,添加精灵的枢轴点。由于它以像素表示,因此将其除以每单位像素可得到正确的偏移量。 要获得该局部点的UV值,请将其除以Sprite边界大小。这将为您提供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;
}
答案 1 :(得分:-1)
您使用的是ScrollRect组件吗?如果没有,你会遇到很多问题,ScrollRect来自新的UI,你不需要编码输入触摸,它会自动为你提供完美的输入识别。
您也可以将滑块添加到ScrollRect。我建议您观看此视频。
将滑块组件添加到ScrollRect以及您可以自定义“不需要担心RayCast忽略”的滑块