From 8d410b42d36ff91129606cf81063f5b7d11d3d27 Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Wed, 26 Nov 2025 10:58:34 +0100 Subject: [PATCH] Finalize capture taking --- .../Scenes/MiniGames/StatueDecoration.unity | 174 ++++++++++++++- .../Controllers/StatueDecorationController.cs | 3 +- .../DragDrop/DecorationDraggableInstance.cs | 1 + .../StatueDressup/Utils/StatuePhotoManager.cs | 68 +++--- Assets/Scripts/Utils/ScreenSpaceUtility.cs | 198 ++++++++++++++++++ .../Scripts/Utils/ScreenSpaceUtility.cs.meta | 3 + .../Utils/TweenAnimationUtility.cs | 6 +- .../Utils/TweenAnimationUtility.cs.meta | 0 8 files changed, 411 insertions(+), 42 deletions(-) create mode 100644 Assets/Scripts/Utils/ScreenSpaceUtility.cs create mode 100644 Assets/Scripts/Utils/ScreenSpaceUtility.cs.meta rename Assets/Scripts/{Minigames/StatueDressup => }/Utils/TweenAnimationUtility.cs (98%) rename Assets/Scripts/{Minigames/StatueDressup => }/Utils/TweenAnimationUtility.cs.meta (100%) diff --git a/Assets/Scenes/MiniGames/StatueDecoration.unity b/Assets/Scenes/MiniGames/StatueDecoration.unity index d0a924dd..5b430854 100644 --- a/Assets/Scenes/MiniGames/StatueDecoration.unity +++ b/Assets/Scenes/MiniGames/StatueDecoration.unity @@ -318,6 +318,42 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 37633365} m_CullTransparentMesh: 1 +--- !u!1 &61401515 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 61401516} + m_Layer: 5 + m_Name: PhotoGallery + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &61401516 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 61401515} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1612917661} + m_Father: {fileID: 1217454518} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &65358844 GameObject: m_ObjectHideFlags: 0 @@ -1274,6 +1310,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1443594949} + - {fileID: 61401516} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -1508,6 +1545,141 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1612917660 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1612917661} + - component: {fileID: 1612917665} + - component: {fileID: 1612917664} + - component: {fileID: 1612917663} + - component: {fileID: 1612917662} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1612917661 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1612917660} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 61401516} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -75, y: -75} + m_SizeDelta: {x: 172.83276, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &1612917662 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1612917660} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.AspectRatioFitter + m_AspectMode: 1 + m_AspectRatio: 0.964 +--- !u!114 &1612917663 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1612917660} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1612917664} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1612917664 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1612917660} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 1917382497509789248, guid: 8d568408ea5f183458e17af541af2d8e, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1612917665 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1612917660} + m_CullTransparentMesh: 1 --- !u!1 &1647993457 GameObject: m_ObjectHideFlags: 0 @@ -1543,7 +1715,7 @@ MonoBehaviour: takePhotoButton: {fileID: 37633367} statue: {fileID: 1078270173} uiElementsToHideForPhoto: [] - photoArea: {fileID: 0} + photoArea: {fileID: 65358845} photoSaveKey: MrCementStatuePhoto --- !u!4 &1647993459 Transform: diff --git a/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs b/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs index fd624a9a..7c4fba71 100644 --- a/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs +++ b/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs @@ -57,7 +57,8 @@ namespace Minigames.StatueDressup.Controllers // Setup photo button if (takePhotoButton != null) { - takePhotoButton.onClick.AddListener(OnTakePhoto); + // TODO: Remove comment when ready + // takePhotoButton.onClick.AddListener(OnTakePhoto); } // Subscribe to menu controller for tracking placed items diff --git a/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs index e4f2f0fb..77481188 100644 --- a/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs +++ b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs @@ -5,6 +5,7 @@ using Minigames.StatueDressup.Utils; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +using Utils; namespace Minigames.StatueDressup.DragDrop { diff --git a/Assets/Scripts/Minigames/StatueDressup/Utils/StatuePhotoManager.cs b/Assets/Scripts/Minigames/StatueDressup/Utils/StatuePhotoManager.cs index 74de576d..ca07c930 100644 --- a/Assets/Scripts/Minigames/StatueDressup/Utils/StatuePhotoManager.cs +++ b/Assets/Scripts/Minigames/StatueDressup/Utils/StatuePhotoManager.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using Core; using UnityEngine; using SDev; +using ScreenUtils = Utils.ScreenSpaceUtility; namespace Minigames.StatueDressup.Utils { @@ -15,15 +15,15 @@ namespace Minigames.StatueDressup.Utils /// public static class StatuePhotoManager { - private const string PHOTO_FOLDER = "StatuePhotos"; - private const string PHOTO_PREFIX = "MrCementStatue_"; - private const string METADATA_KEY_PREFIX = "StatuePhoto_Meta_"; - private const string PHOTO_INDEX_KEY = "StatuePhoto_Index"; + private const string PhotoFolder = "StatuePhotos"; + private const string PhotoPrefix = "MrCementStatue_"; + private const string MetadataKeyPrefix = "StatuePhoto_Meta_"; + private const string PhotoIndexKey = "StatuePhoto_Index"; /// /// Photo metadata stored in PlayerPrefs /// - [System.Serializable] + [Serializable] public class PhotoMetadata { public string photoId; @@ -40,7 +40,12 @@ namespace Minigames.StatueDressup.Utils /// RectTransform defining the capture region /// Callback with captured Texture2D /// Camera used for coordinate conversion (null = Camera.main) - public static void CaptureAreaPhoto(RectTransform captureArea, Action onComplete, Camera mainCamera = null) + /// If true, clamps capture area to visible screen bounds + public static void CaptureAreaPhoto( + RectTransform captureArea, + Action onComplete, + Camera mainCamera = null, + bool clampToScreenBounds = true) { if (captureArea == null) { @@ -51,8 +56,14 @@ namespace Minigames.StatueDressup.Utils if (mainCamera == null) mainCamera = Camera.main; - // Get screen rect from RectTransform - Rect screenRect = GetScreenRectFromRectTransform(captureArea, mainCamera); + // Use ScreenSpaceUtility to convert RectTransform to screen rect + // returnCenterPosition = true because ScreenshotHelper expects center position + Rect screenRect = ScreenUtils.RectTransformToScreenRect( + captureArea, + mainCamera, + clampToScreenBounds, + returnCenterPosition: true + ); Logging.Debug($"[StatuePhotoManager] Capturing area: pos={screenRect.position}, size={screenRect.size}"); @@ -60,7 +71,7 @@ namespace Minigames.StatueDressup.Utils ScreenshotHelper.Instance.Capture( screenRect.position, screenRect.size, - (Texture2D texture) => + (texture) => { if (texture != null) { @@ -75,24 +86,7 @@ namespace Minigames.StatueDressup.Utils } ); } - - /// - /// Convert RectTransform world corners to screen space rect - /// - private static Rect GetScreenRectFromRectTransform(RectTransform rectTransform, Camera camera) - { - Vector3[] corners = new Vector3[4]; - rectTransform.GetWorldCorners(corners); - - Vector2 min = RectTransformUtility.WorldToScreenPoint(camera, corners[0]); - Vector2 max = RectTransformUtility.WorldToScreenPoint(camera, corners[2]); - - // Ensure positive dimensions - float width = Mathf.Abs(max.x - min.x); - float height = Mathf.Abs(max.y - min.y); - - return new Rect(min.x, min.y, width, height); - } + #endregion @@ -115,13 +109,13 @@ namespace Minigames.StatueDressup.Utils try { // Generate unique photo ID - string photoId = $"{PHOTO_PREFIX}{DateTime.Now.Ticks}"; + string photoId = $"{PhotoPrefix}{DateTime.Now.Ticks}"; // Save texture using FileSaveUtil string savedPath = FileSaveUtil.Instance.SaveTextureAsPNG( photo, FileSaveUtil.AppPath.PersistentDataPath, - PHOTO_FOLDER, + PhotoFolder, photoId ); @@ -232,7 +226,7 @@ namespace Minigames.StatueDressup.Utils /// public static List GetAllPhotoIds() { - string indexJson = PlayerPrefs.GetString(PHOTO_INDEX_KEY, "[]"); + string indexJson = PlayerPrefs.GetString(PhotoIndexKey, "[]"); List photoIds = JsonUtility.FromJson(WrapJsonArray(indexJson))?.ids ?? new List(); // Sort by timestamp descending (newest first) @@ -328,7 +322,7 @@ namespace Minigames.StatueDressup.Utils public static string GetPhotoDirectory() { - return Path.Combine(Application.persistentDataPath, PHOTO_FOLDER); + return Path.Combine(Application.persistentDataPath, PhotoFolder); } private static string GetPhotoFilePath(string photoId) @@ -339,19 +333,19 @@ namespace Minigames.StatueDressup.Utils private static void SaveMetadata(PhotoMetadata metadata) { string json = JsonUtility.ToJson(metadata); - PlayerPrefs.SetString(METADATA_KEY_PREFIX + metadata.photoId, json); + PlayerPrefs.SetString(MetadataKeyPrefix + metadata.photoId, json); PlayerPrefs.Save(); } private static PhotoMetadata LoadMetadata(string photoId) { - string json = PlayerPrefs.GetString(METADATA_KEY_PREFIX + photoId, null); + string json = PlayerPrefs.GetString(MetadataKeyPrefix + photoId, null); return string.IsNullOrEmpty(json) ? null : JsonUtility.FromJson(json); } private static void DeleteMetadata(string photoId) { - PlayerPrefs.DeleteKey(METADATA_KEY_PREFIX + photoId); + PlayerPrefs.DeleteKey(MetadataKeyPrefix + photoId); PlayerPrefs.Save(); } @@ -377,7 +371,7 @@ namespace Minigames.StatueDressup.Utils private static void SavePhotoIndex(List photoIds) { string json = JsonUtility.ToJson(new PhotoIdList { ids = photoIds }); - PlayerPrefs.SetString(PHOTO_INDEX_KEY, json); + PlayerPrefs.SetString(PhotoIndexKey, json); PlayerPrefs.Save(); } @@ -387,7 +381,7 @@ namespace Minigames.StatueDressup.Utils return json; } - [System.Serializable] + [Serializable] private class PhotoIdList { public List ids = new List(); diff --git a/Assets/Scripts/Utils/ScreenSpaceUtility.cs b/Assets/Scripts/Utils/ScreenSpaceUtility.cs new file mode 100644 index 00000000..b2061f1f --- /dev/null +++ b/Assets/Scripts/Utils/ScreenSpaceUtility.cs @@ -0,0 +1,198 @@ +using Core; +using UnityEngine; + +namespace Utils +{ + /// + /// Utility methods for screen space and UI coordinate conversions + /// + public static class ScreenSpaceUtility + { + /// + /// Convert RectTransform to screen space rect with center position. + /// Useful for screenshot capture or screen-based calculations. + /// + /// RectTransform to convert + /// Camera used for coordinate conversion (null = Camera.main) + /// If true, clamps the rect to visible screen area + /// If true, returns center position; if false, returns bottom-left position + /// Screen space rect (position is center or bottom-left based on returnCenterPosition) + public static Rect RectTransformToScreenRect( + RectTransform rectTransform, + Camera camera = null, + bool clampToScreenBounds = true, + bool returnCenterPosition = true) + { + if (rectTransform == null) + { + Logging.Error("[ScreenSpaceUtility] RectTransform is null!"); + return new Rect(Screen.width / 2f, Screen.height / 2f, 0, 0); + } + + if (camera == null) camera = Camera.main; + + // Get world corners (0=bottom-left, 1=top-left, 2=top-right, 3=bottom-right) + Vector3[] corners = new Vector3[4]; + rectTransform.GetWorldCorners(corners); + + // Determine correct camera based on Canvas render mode + Camera canvasCamera = GetCanvasCamera(rectTransform, camera); + + // Convert corners to screen space + Vector2 min = RectTransformUtility.WorldToScreenPoint(canvasCamera, corners[0]); + Vector2 max = RectTransformUtility.WorldToScreenPoint(canvasCamera, corners[2]); + + Logging.Debug($"[ScreenSpaceUtility] Canvas mode: {rectTransform.GetComponentInParent()?.renderMode}, Camera: {canvasCamera?.name ?? "null"}"); + Logging.Debug($"[ScreenSpaceUtility] Raw screen coords - min: {min}, max: {max}"); + + // Apply screen bounds clamping if requested + if (clampToScreenBounds) + { + return ClampRectToScreenBounds(min, max, returnCenterPosition); + } + else + { + // No clamping - use raw values + float width = Mathf.Abs(max.x - min.x); + float height = Mathf.Abs(max.y - min.y); + + if (returnCenterPosition) + { + float centerX = min.x + width / 2f; + float centerY = min.y + height / 2f; + return new Rect(centerX, centerY, width, height); + } + else + { + return new Rect(min.x, min.y, width, height); + } + } + } + + /// + /// Get the appropriate camera for UI coordinate conversion based on Canvas render mode + /// + /// RectTransform to find canvas for + /// Fallback camera if no canvas found + /// Camera to use for coordinate conversion (null for Overlay mode) + public static Camera GetCanvasCamera(RectTransform rectTransform, Camera fallbackCamera = null) + { + Canvas canvas = rectTransform.GetComponentInParent(); + + if (canvas == null) + { + return fallbackCamera; + } + + switch (canvas.renderMode) + { + case RenderMode.ScreenSpaceOverlay: + // For Screen Space - Overlay, use null (direct pixel coords) + return null; + + case RenderMode.ScreenSpaceCamera: + // For Screen Space - Camera, use the canvas's worldCamera + return canvas.worldCamera; + + case RenderMode.WorldSpace: + // For World Space, use canvas camera or fallback + return canvas.worldCamera ?? fallbackCamera; + + default: + return fallbackCamera; + } + } + + /// + /// Clamp rect coordinates to screen bounds and calculate final rect + /// + /// Bottom-left corner in screen space + /// Top-right corner in screen space + /// If true, returns center position; if false, returns bottom-left + /// Clamped screen rect + private static Rect ClampRectToScreenBounds(Vector2 min, Vector2 max, bool returnCenterPosition) + { + // Clamp to screen bounds + float minX = Mathf.Max(0, min.x); + float minY = Mathf.Max(0, min.y); + float maxX = Mathf.Min(Screen.width, max.x); + float maxY = Mathf.Min(Screen.height, max.y); + + // Check if rect is completely outside screen bounds + if (minX >= Screen.width || minY >= Screen.height || maxX <= 0 || maxY <= 0) + { + Logging.Warning("[ScreenSpaceUtility] RectTransform is completely outside screen bounds!"); + return new Rect(Screen.width / 2f, Screen.height / 2f, 0, 0); + } + + // Calculate dimensions from clamped bounds + float width = maxX - minX; + float height = maxY - minY; + + // Validate dimensions + if (width <= 0 || height <= 0) + { + Logging.Warning($"[ScreenSpaceUtility] Invalid dimensions after clamping: {width}x{height}"); + return new Rect(Screen.width / 2f, Screen.height / 2f, 100, 100); // Fallback small rect + } + + Logging.Debug($"[ScreenSpaceUtility] Clamped bounds - min: ({minX}, {minY}), max: ({maxX}, {maxY})"); + + if (returnCenterPosition) + { + // Calculate center position from clamped bounds + float centerX = minX + width / 2f; + float centerY = minY + height / 2f; + + Logging.Debug($"[ScreenSpaceUtility] Final rect - center: ({centerX}, {centerY}), size: ({width}, {height})"); + return new Rect(centerX, centerY, width, height); + } + else + { + // Return bottom-left position + Logging.Debug($"[ScreenSpaceUtility] Final rect - position: ({minX}, {minY}), size: ({width}, {height})"); + return new Rect(minX, minY, width, height); + } + } + + /// + /// Check if a screen rect is completely outside screen bounds + /// + public static bool IsRectOutsideScreenBounds(Rect rect) + { + return rect.xMax < 0 || rect.xMin > Screen.width || + rect.yMax < 0 || rect.yMin > Screen.height; + } + + /// + /// Get the visible portion of a rect when clamped to screen bounds + /// + public static Rect GetVisibleScreenRect(Rect rect) + { + float minX = Mathf.Max(0, rect.xMin); + float minY = Mathf.Max(0, rect.yMin); + float maxX = Mathf.Min(Screen.width, rect.xMax); + float maxY = Mathf.Min(Screen.height, rect.yMax); + + float width = Mathf.Max(0, maxX - minX); + float height = Mathf.Max(0, maxY - minY); + + return new Rect(minX, minY, width, height); + } + + /// + /// Calculate the percentage of a rect that is visible on screen + /// + public static float GetVisiblePercentage(Rect rect) + { + if (rect.width <= 0 || rect.height <= 0) return 0f; + + Rect visibleRect = GetVisibleScreenRect(rect); + float totalArea = rect.width * rect.height; + float visibleArea = visibleRect.width * visibleRect.height; + + return visibleArea / totalArea; + } + } +} + diff --git a/Assets/Scripts/Utils/ScreenSpaceUtility.cs.meta b/Assets/Scripts/Utils/ScreenSpaceUtility.cs.meta new file mode 100644 index 00000000..279d001c --- /dev/null +++ b/Assets/Scripts/Utils/ScreenSpaceUtility.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f9a38b4740894e6ea8c32d8f62bc5bd6 +timeCreated: 1764148562 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs b/Assets/Scripts/Utils/TweenAnimationUtility.cs similarity index 98% rename from Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs rename to Assets/Scripts/Utils/TweenAnimationUtility.cs index 50699db0..5859af82 100644 --- a/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs +++ b/Assets/Scripts/Utils/TweenAnimationUtility.cs @@ -1,9 +1,9 @@ -using Pixelplacement; +using System; +using Pixelplacement; using Pixelplacement.TweenSystem; using UnityEngine; -using System; -namespace Minigames.StatueDressup.Utils +namespace Utils { /// /// Common animation utilities extracted from CardAnimator pattern. diff --git a/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs.meta b/Assets/Scripts/Utils/TweenAnimationUtility.cs.meta similarity index 100% rename from Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs.meta rename to Assets/Scripts/Utils/TweenAnimationUtility.cs.meta