Skip to content

Instantly share code, notes, and snippets.

@fum1h1ro
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fum1h1ro/583df14ab71dd972fc57 to your computer and use it in GitHub Desktop.
Save fum1h1ro/583df14ab71dd972fc57 to your computer and use it in GitHub Desktop.
GraphicRaycaster2: Addapt for RenderTexture
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.EventSystems;
namespace UnityEngine.UI
{
[AddComponentMenu("Event/Graphic Raycaster 2")]
[RequireComponent(typeof(Canvas))]
public class GraphicRaycaster2 : BaseRaycaster
{
protected const int kNoEventMaskSet = -1;
public enum BlockingObjects
{
None = 0,
TwoD = 1,
ThreeD = 2,
All = 3,
}
public override int sortOrderPriority
{
get
{
// We need to return the sorting order here as distance will all be 0 for overlay.
if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)
return canvas.sortingOrder;
return base.sortOrderPriority;
}
}
public override int renderOrderPriority
{
get
{
// We need to return the sorting order here as distance will all be 0 for overlay.
if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)
return canvas.renderOrder;
return base.renderOrderPriority;
}
}
[SerializeField]
private bool m_IgnoreReversedGraphics = true;
[SerializeField]
private BlockingObjects m_BlockingObjects = BlockingObjects.None;
public bool ignoreReversedGraphics { get {return m_IgnoreReversedGraphics; } set{ m_IgnoreReversedGraphics = value; } }
public BlockingObjects blockingObjects { get {return m_BlockingObjects; } set{ m_BlockingObjects = value; } }
[SerializeField]
protected LayerMask m_BlockingMask = kNoEventMaskSet;
private Canvas m_Canvas;
protected GraphicRaycaster2()
{ }
private Canvas canvas
{
get
{
if (m_Canvas != null)
return m_Canvas;
m_Canvas = GetComponent<Canvas>();
return m_Canvas;
}
}
[NonSerialized] private List<Graphic> m_RaycastResults = new List<Graphic>();
public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)
{
if (canvas == null)
return;
// Convert to view space
Vector2 pos;
if (eventCamera == null)
pos = new Vector2(eventData.position.x / Screen.width, eventData.position.y / Screen.height);
else
pos = eventCamera.ScreenToViewportPoint(eventData.position / canvas.scaleFactor);
//@Debug.Log(pos);
// If it's outside the camera's viewport, do nothing
if (pos.x < 0f || pos.x > 1f || pos.y < 0f || pos.y > 1f)
return;
float hitDistance = float.MaxValue;
Ray ray = new Ray();
if (eventCamera != null)
ray = eventCamera.ScreenPointToRay(eventData.position / canvas.scaleFactor);
if (canvas.renderMode != RenderMode.ScreenSpaceOverlay && blockingObjects != BlockingObjects.None)
{
float dist = eventCamera.farClipPlane - eventCamera.nearClipPlane;
if (blockingObjects == BlockingObjects.ThreeD || blockingObjects == BlockingObjects.All)
{
RaycastHit hit;
if (Physics.Raycast(ray, out hit, dist, m_BlockingMask))
{
hitDistance = hit.distance;
}
}
if (blockingObjects == BlockingObjects.TwoD || blockingObjects == BlockingObjects.All)
{
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, dist, m_BlockingMask);
if (hit.collider != null)
{
hitDistance = hit.fraction * dist;
}
}
}
m_RaycastResults.Clear();
if (eventCamera != null)
Raycast(canvas, eventCamera, eventData.position / canvas.scaleFactor, m_RaycastResults);
else
Raycast(canvas, eventCamera, eventData.position, m_RaycastResults);
for (var index = 0; index < m_RaycastResults.Count; index++)
{
var go = m_RaycastResults[index].gameObject;
bool appendGraphic = true;
if (ignoreReversedGraphics)
{
if (eventCamera == null)
{
// If we dont have a camera we know that we should always be facing forward
var dir = go.transform.rotation * Vector3.forward;
appendGraphic = Vector3.Dot(Vector3.forward, dir) > 0;
}
else
{
// If we have a camera compare the direction against the cameras forward.
var cameraFoward = eventCamera.transform.rotation * Vector3.forward;
var dir = go.transform.rotation * Vector3.forward;
appendGraphic = Vector3.Dot(cameraFoward, dir) > 0;
}
}
if (appendGraphic)
{
float distance = 0;
if (eventCamera == null || canvas.renderMode == RenderMode.ScreenSpaceOverlay)
distance = 0;
else
{
// http://geomalgorithms.com/a06-_intersect-2.html
distance = (Vector3.Dot(go.transform.forward, go.transform.position - ray.origin) / Vector3.Dot(go.transform.forward, ray.direction));
// Check to see if the go is behind the camera.
if (distance < 0)
continue;
}
if (distance >= hitDistance)
continue;
var castResult = new RaycastResult
{
gameObject = go,
module = this,
distance = distance,
index = resultAppendList.Count,
depth = m_RaycastResults[index].depth,
sortingLayer = canvas.sortingLayerID,
sortingOrder = canvas.sortingOrder
};
resultAppendList.Add(castResult);
}
}
}
public override Camera eventCamera
{
get
{
if (canvas.renderMode == RenderMode.ScreenSpaceOverlay
|| (canvas.renderMode == RenderMode.ScreenSpaceCamera && canvas.worldCamera == null))
return null;
return canvas.worldCamera != null ? canvas.worldCamera : Camera.main;
}
}
/// <summary>
/// Perform a raycast into the screen and collect all graphics underneath it.
/// </summary>
[NonSerialized] static readonly List<Graphic> s_SortedGraphics = new List<Graphic>();
private static void Raycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, List<Graphic> results)
{
// Debug.Log("ttt" + pointerPoision + ":::" + camera);
// Necessary for the event system
var foundGraphics = GraphicRegistry.GetGraphicsForCanvas(canvas);
s_SortedGraphics.Clear();
for (int i = 0; i < foundGraphics.Count; ++i)
{
Graphic graphic = foundGraphics[i];
// -1 means it hasn't been processed by the canvas, which means it isn't actually drawn
if (graphic.depth == -1)
continue;
if (!RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera))
continue;
if (graphic.Raycast(pointerPosition, eventCamera))
{
s_SortedGraphics.Add(graphic);
}
}
s_SortedGraphics.Sort((g1, g2) => g2.depth.CompareTo(g1.depth));
// StringBuilder cast = new StringBuilder();
for (int i = 0; i < s_SortedGraphics.Count; ++i)
results.Add(s_SortedGraphics[i]);
// Debug.Log (cast.ToString());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment