Skip to content

Instantly share code, notes, and snippets.

@nikescar1
Created September 23, 2022 00:02
Show Gist options
  • Save nikescar1/7a2ef665bc7c988e7c38b190fae3d230 to your computer and use it in GitHub Desktop.
Save nikescar1/7a2ef665bc7c988e7c38b190fae3d230 to your computer and use it in GitHub Desktop.
UI Image using Sprite Physics Shape for canvas raycasting
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ImagePhysicsShapeRaycasting : Image, ICanvasRaycastFilter, ISerializationCallbackReceiver, ILayoutElement
{
private List<Vector2> physicsShape = new List<Vector2>();
new void Start()
{
base.Start();
sprite.GetPhysicsShape(0, physicsShape);
Rect spriteRect = rectTransform.rect;
float width = overrideSprite.texture.width;
float height = overrideSprite.texture.height;
for(int i= 0; i < physicsShape.Count; i++)
{
Vector2 point = physicsShape[i];
Vector2 newPoint = new Vector2(point.x / (width * .005f) * (spriteRect.width * .5f), point.y / (height * .005f) * (spriteRect.height * .5f));
physicsShape[i] = newPoint;
}
}
public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
{
if (overrideSprite == null)
return true;
Vector2 local;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out local))
return false;
return IsPointInPolygon(local, physicsShape);
}
public bool IsPointInPolygon(Vector2 point, List<Vector2> polygon)
{
int polygonLength = polygon.Count, i = 0;
bool inside = false;
// x, y for tested point.
float pointX = point.x, pointY = point.y;
// start / end point for the current polygon segment.
float startX, startY, endX, endY;
Vector2 endPoint = polygon[polygonLength - 1];
endX = endPoint.x;
endY = endPoint.y;
while (i < polygonLength)
{
startX = endX; startY = endY;
endPoint = polygon[i++];
endX = endPoint.x; endY = endPoint.y;
//
inside ^= (endY > pointY ^ startY > pointY) /* ? pointY inside [startY;endY] segment ? */
&& /* if so, test if it is under the segment */
((pointX - endX) < (pointY - endY) * (startX - endX) / (startY - endY));
}
return inside;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment