forked from Shardstone/trail-into-darkness
added a disfunctionalk popup system
This commit is contained in:
@@ -45,6 +45,8 @@ namespace Jovian.PopupSystem.UI {
|
||||
float maxWidth;
|
||||
bool isVisible;
|
||||
bool layoutDirty;
|
||||
Canvas rootCanvas;
|
||||
Camera canvasCamera;
|
||||
|
||||
public CanvasGroup CanvasGroup => canvasGroup;
|
||||
public RectTransform Content => content;
|
||||
@@ -172,9 +174,20 @@ namespace Jovian.PopupSystem.UI {
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheCanvas() {
|
||||
if(rootCanvas != null) {
|
||||
return;
|
||||
}
|
||||
rootCanvas = GetComponentInParent<Canvas>()?.rootCanvas;
|
||||
canvasCamera = rootCanvas != null && rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay
|
||||
? rootCanvas.worldCamera : null;
|
||||
}
|
||||
|
||||
private void PositionAnchoredTo(RectTransform target, AnchorSide side) {
|
||||
var targetRect = GetScreenRect(target);
|
||||
var popupSize = GetScreenRect((RectTransform)transform).size;
|
||||
CacheCanvas();
|
||||
var targetRect = GetScreenRect(target, canvasCamera);
|
||||
var popupRect = GetScreenRect((RectTransform)transform, canvasCamera);
|
||||
var popupSize = popupRect.size;
|
||||
|
||||
var pos = side switch {
|
||||
AnchorSide.Below => new Vector2(targetRect.center.x - popupSize.x * 0.5f, targetRect.yMin - popupSize.y),
|
||||
@@ -188,26 +201,36 @@ namespace Jovian.PopupSystem.UI {
|
||||
}
|
||||
|
||||
private void PositionAtScreenPoint(Vector2 screenPos) {
|
||||
CacheCanvas();
|
||||
var rt = (RectTransform)transform;
|
||||
if(layoutDirty) {
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
|
||||
layoutDirty = false;
|
||||
}
|
||||
var popupSize = rt.rect.size;
|
||||
var popupSize = GetScreenRect(rt, canvasCamera).size;
|
||||
|
||||
// Clamp to screen
|
||||
screenPos.x = Mathf.Clamp(screenPos.x, screenEdgePadding, Screen.width - popupSize.x - screenEdgePadding);
|
||||
screenPos.y = Mathf.Clamp(screenPos.y, screenEdgePadding, Screen.height - popupSize.y - screenEdgePadding);
|
||||
|
||||
rt.position = screenPos;
|
||||
// Convert screen position to parent local space
|
||||
var parentRt = rt.parent as RectTransform;
|
||||
if(parentRt != null) {
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRt, screenPos, canvasCamera, out var localPos);
|
||||
rt.localPosition = localPos;
|
||||
}
|
||||
else {
|
||||
rt.position = screenPos;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Vector3[] cornersBuffer = new Vector3[4];
|
||||
|
||||
private static Rect GetScreenRect(RectTransform rt) {
|
||||
private static Rect GetScreenRect(RectTransform rt, Camera camera) {
|
||||
rt.GetWorldCorners(cornersBuffer);
|
||||
var min = new Vector2(cornersBuffer[0].x, cornersBuffer[0].y);
|
||||
var max = new Vector2(cornersBuffer[2].x, cornersBuffer[2].y);
|
||||
// Convert world corners to screen space
|
||||
var min = RectTransformUtility.WorldToScreenPoint(camera, cornersBuffer[0]);
|
||||
var max = RectTransformUtility.WorldToScreenPoint(camera, cornersBuffer[2]);
|
||||
return new Rect(min, max - min);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user