Finalize capture taking
This commit is contained in:
committed by
Michal Pikulski
parent
5ad84ca3e8
commit
8d410b42d3
@@ -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
|
||||
|
||||
@@ -5,6 +5,7 @@ using Minigames.StatueDressup.Utils;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using Utils;
|
||||
|
||||
namespace Minigames.StatueDressup.DragDrop
|
||||
{
|
||||
|
||||
@@ -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
|
||||
/// </summary>
|
||||
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";
|
||||
|
||||
/// <summary>
|
||||
/// Photo metadata stored in PlayerPrefs
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[Serializable]
|
||||
public class PhotoMetadata
|
||||
{
|
||||
public string photoId;
|
||||
@@ -40,7 +40,12 @@ namespace Minigames.StatueDressup.Utils
|
||||
/// <param name="captureArea">RectTransform defining the capture region</param>
|
||||
/// <param name="onComplete">Callback with captured Texture2D</param>
|
||||
/// <param name="mainCamera">Camera used for coordinate conversion (null = Camera.main)</param>
|
||||
public static void CaptureAreaPhoto(RectTransform captureArea, Action<Texture2D> onComplete, Camera mainCamera = null)
|
||||
/// <param name="clampToScreenBounds">If true, clamps capture area to visible screen bounds</param>
|
||||
public static void CaptureAreaPhoto(
|
||||
RectTransform captureArea,
|
||||
Action<Texture2D> 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
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert RectTransform world corners to screen space rect
|
||||
/// </summary>
|
||||
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
|
||||
/// </summary>
|
||||
public static List<string> GetAllPhotoIds()
|
||||
{
|
||||
string indexJson = PlayerPrefs.GetString(PHOTO_INDEX_KEY, "[]");
|
||||
string indexJson = PlayerPrefs.GetString(PhotoIndexKey, "[]");
|
||||
List<string> photoIds = JsonUtility.FromJson<PhotoIdList>(WrapJsonArray(indexJson))?.ids ?? new List<string>();
|
||||
|
||||
// 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<PhotoMetadata>(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<string> 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<string> ids = new List<string>();
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
using Pixelplacement;
|
||||
using Pixelplacement.TweenSystem;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace Minigames.StatueDressup.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Common animation utilities extracted from CardAnimator pattern.
|
||||
/// Provides reusable tween animations for UI elements.
|
||||
/// </summary>
|
||||
public static class TweenAnimationUtility
|
||||
{
|
||||
#region Scale Animations
|
||||
|
||||
/// <summary>
|
||||
/// Animate scale to target value with ease in-out
|
||||
/// </summary>
|
||||
public static TweenBase AnimateScale(Transform transform, Vector3 targetScale, float duration, Action onComplete = null)
|
||||
{
|
||||
return Tween.LocalScale(transform, targetScale, duration, 0f, Tween.EaseInOut, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulse scale animation (scale up then back to original)
|
||||
/// </summary>
|
||||
public static void PulseScale(Transform transform, float pulseAmount = 1.1f, float duration = 0.2f, Action onComplete = null)
|
||||
{
|
||||
Vector3 originalScale = transform.localScale;
|
||||
Vector3 pulseScale = originalScale * pulseAmount;
|
||||
|
||||
Tween.LocalScale(transform, pulseScale, duration, 0f, Tween.EaseOutBack,
|
||||
completeCallback: () =>
|
||||
{
|
||||
Tween.LocalScale(transform, originalScale, duration, 0f, Tween.EaseInBack, completeCallback: onComplete);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pop-in animation (scale from 0 to target with overshoot)
|
||||
/// </summary>
|
||||
public static TweenBase PopIn(Transform transform, Vector3 targetScale, float duration = 0.5f, Action onComplete = null)
|
||||
{
|
||||
transform.localScale = Vector3.zero;
|
||||
return Tween.LocalScale(transform, targetScale, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pop-out animation (scale from current to 0)
|
||||
/// </summary>
|
||||
public static TweenBase PopOut(Transform transform, float duration = 0.3f, Action onComplete = null)
|
||||
{
|
||||
return Tween.LocalScale(transform, Vector3.zero, duration, 0f, Tween.EaseInBack, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Smooth scale transition with bounce
|
||||
/// </summary>
|
||||
public static TweenBase ScaleWithBounce(Transform transform, Vector3 targetScale, float duration, Action onComplete = null)
|
||||
{
|
||||
return Tween.LocalScale(transform, targetScale, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Position Animations
|
||||
|
||||
/// <summary>
|
||||
/// Animate anchored position (for RectTransform UI elements)
|
||||
/// </summary>
|
||||
public static TweenBase AnimateAnchoredPosition(RectTransform rectTransform, Vector2 targetPosition, float duration, Action onComplete = null)
|
||||
{
|
||||
return Tween.AnchoredPosition(rectTransform, targetPosition, duration, 0f, Tween.EaseInOut, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Animate local position (for regular transforms)
|
||||
/// </summary>
|
||||
public static TweenBase AnimateLocalPosition(Transform transform, Vector3 targetPosition, float duration, Action onComplete = null)
|
||||
{
|
||||
return Tween.LocalPosition(transform, targetPosition, duration, 0f, Tween.EaseInOut, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move with bounce effect
|
||||
/// </summary>
|
||||
public static TweenBase MoveWithBounce(RectTransform rectTransform, Vector2 targetPosition, float duration, Action onComplete = null)
|
||||
{
|
||||
return Tween.AnchoredPosition(rectTransform, targetPosition, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Combined Hover Animations
|
||||
|
||||
/// <summary>
|
||||
/// Hover enter animation (lift and scale) for RectTransform
|
||||
/// </summary>
|
||||
public static void HoverEnter(RectTransform rectTransform, Vector2 originalPosition, float liftAmount = 20f,
|
||||
float scaleMultiplier = 1.05f, float duration = 0.2f, Action onComplete = null)
|
||||
{
|
||||
Vector2 targetPos = originalPosition + Vector2.up * liftAmount;
|
||||
|
||||
Tween.AnchoredPosition(rectTransform, targetPos, duration, 0f, Tween.EaseOutBack);
|
||||
Tween.LocalScale(rectTransform, Vector3.one * scaleMultiplier, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hover exit animation (return to original position and scale) for RectTransform
|
||||
/// </summary>
|
||||
public static void HoverExit(RectTransform rectTransform, Vector2 originalPosition, float duration = 0.2f, Action onComplete = null)
|
||||
{
|
||||
Tween.AnchoredPosition(rectTransform, originalPosition, duration, 0f, Tween.EaseInBack);
|
||||
Tween.LocalScale(rectTransform, Vector3.one, duration, 0f, Tween.EaseInBack, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Glow pulse effect (scale up/down repeatedly)
|
||||
/// </summary>
|
||||
public static TweenBase StartGlowPulse(Transform transform, float pulseAmount = 1.1f, float duration = 0.8f)
|
||||
{
|
||||
Vector3 originalScale = transform.localScale;
|
||||
Vector3 pulseScale = originalScale * pulseAmount;
|
||||
|
||||
return Tween.LocalScale(transform, pulseScale, duration, 0f, Tween.EaseIn, Tween.LoopType.PingPong);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop any active tweens on transform
|
||||
/// </summary>
|
||||
public static void StopTweens(Transform transform)
|
||||
{
|
||||
Tween.Cancel(transform.GetInstanceID());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fade Animations
|
||||
|
||||
/// <summary>
|
||||
/// Fade CanvasGroup alpha
|
||||
/// </summary>
|
||||
public static TweenBase FadeCanvasGroup(CanvasGroup canvasGroup, float targetAlpha, float duration, Action onComplete = null)
|
||||
{
|
||||
return Tween.CanvasGroupAlpha(canvasGroup, targetAlpha, duration, 0f, Tween.EaseInOut, completeCallback: onComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pop-out with fade - scale to 0 and fade out simultaneously
|
||||
/// </summary>
|
||||
public static void PopOutWithFade(Transform transform, CanvasGroup canvasGroup, float duration, Action onComplete = null)
|
||||
{
|
||||
// Scale to 0
|
||||
Tween.LocalScale(transform, Vector3.zero, duration, 0f, Tween.EaseInBack);
|
||||
|
||||
// Fade out simultaneously
|
||||
if (canvasGroup != null)
|
||||
{
|
||||
Tween.CanvasGroupAlpha(canvasGroup, 0f, duration, 0f, Tween.EaseInOut, completeCallback: onComplete);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no canvas group, just call complete after scale
|
||||
Tween.LocalScale(transform, Vector3.zero, duration, 0f, Tween.EaseInBack, completeCallback: onComplete);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abd48147eff149508890fe2fa87b8421
|
||||
timeCreated: 1763745490
|
||||
Reference in New Issue
Block a user