Add backbone for card creation and implement Camera minigame mechanics

This commit is contained in:
Michal Pikulski
2025-10-10 14:31:51 +02:00
parent d9039ce655
commit 0c5546efd2
107 changed files with 10490 additions and 280 deletions

View File

@@ -182,7 +182,7 @@ public class GameManager : MonoBehaviour
// Resume all registered components
foreach (var component in _pausableComponents)
{
component.Resume();
component.DoResume();
}
// Broadcast resume event

View File

@@ -15,7 +15,7 @@ namespace AppleHills.Core.Interfaces
/// <summary>
/// Resumes the component's functionality
/// </summary>
void Resume();
void DoResume();
/// <summary>
/// Gets whether the component is currently paused

View File

@@ -0,0 +1,164 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using Input;
using Settings;
namespace Utility
{
public class SceneOrientationEnforcer : MonoBehaviour
{
private static SceneOrientationEnforcer _instance;
private static bool _isQuitting;
public static SceneOrientationEnforcer Instance
{
get
{
if (_instance == null && Application.isPlaying && !_isQuitting)
{
_instance = FindAnyObjectByType<SceneOrientationEnforcer>();
if (_instance == null)
{
var go = new GameObject("SceneOrientationEnforcer");
_instance = go.AddComponent<SceneOrientationEnforcer>();
// DontDestroyOnLoad(go); // Uncomment if you want persistence
}
}
return _instance;
}
}
[Header("Config")]
public SceneOrientationConfig orientationConfig;
public GameObject orientationPromptPrefab;
public event Action OnOrientationCorrect;
private GameObject promptInstance;
private ScreenOrientationRequirement requiredOrientation;
private bool orientationCorrect;
private Coroutine orientationCheckCoroutine;
void Awake()
{
_instance = this;
OnOrientationCorrect += HandleOrientationCorrect;
}
void Start()
{
// Subscribe to sceneLoaded event
SceneManager.sceneLoaded += OnSceneLoaded;
// Manually invoke for the first scene (unless it's Main Menu)
var activeScene = SceneManager.GetActiveScene();
if (!IsMainMenuScene(activeScene))
{
OnSceneLoaded(activeScene, LoadSceneMode.Single);
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// Clean up any previous prompt/coroutine
// CleanupPromptAndCoroutine();
if (IsMainMenuScene(scene))
return;
requiredOrientation = orientationConfig != null ? orientationConfig.GetRequirementForScene(scene.name) : ScreenOrientationRequirement.Portrait;
orientationCorrect = IsOrientationCorrect();
if (!orientationCorrect)
{
InputManager.Instance.SetInputMode(InputMode.UI);
ShowPrompt();
orientationCheckCoroutine = StartCoroutine(OrientationCheckRoutine());
}
else
{
orientationCorrect = true;
OnOrientationCorrect?.Invoke();
}
}
private bool IsMainMenuScene(Scene scene)
{
// Adjust this logic if you have a different main menu scene name
return scene.name == "Main Menu" || scene.name == "MainMenu";
}
/// <summary>
/// Checks if the current device orientation matches the required orientation for the scene
/// </summary>
/// <returns>True if the orientation is correct, false otherwise</returns>
public bool IsOrientationCorrect()
{
switch (requiredOrientation)
{
case ScreenOrientationRequirement.Portrait:
return Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown;
case ScreenOrientationRequirement.Landscape:
return Screen.orientation == ScreenOrientation.LandscapeLeft || Screen.orientation == ScreenOrientation.LandscapeRight;
default:
return true;
}
}
private System.Collections.IEnumerator OrientationCheckRoutine()
{
while (!IsOrientationCorrect())
{
yield return new WaitForSeconds(0.5f);
}
orientationCorrect = true;
OnOrientationCorrect?.Invoke();
}
private void ShowPrompt()
{
if (orientationPromptPrefab != null && promptInstance == null)
{
promptInstance = Instantiate(orientationPromptPrefab);
DontDestroyOnLoad(promptInstance);
}
}
private void HandleOrientationCorrect()
{
if (promptInstance != null)
{
Destroy(promptInstance);
promptInstance = null;
}
if (orientationCheckCoroutine != null)
{
StopCoroutine(orientationCheckCoroutine);
orientationCheckCoroutine = null;
}
InputManager.Instance.SetInputMode(InputMode.Game);
}
private void CleanupPromptAndCoroutine()
{
if (promptInstance != null)
{
Destroy(promptInstance);
promptInstance = null;
}
if (orientationCheckCoroutine != null)
{
StopCoroutine(orientationCheckCoroutine);
orientationCheckCoroutine = null;
}
}
void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
OnOrientationCorrect -= HandleOrientationCorrect;
}
void OnApplicationQuit()
{
_isQuitting = true;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5be782e6ff7641519b9bad2e7552d4e8
timeCreated: 1757316712

View File

@@ -126,6 +126,38 @@ namespace AppleHills.Core.Settings
[Tooltip("Whether to block player input during bump movement")]
[SerializeField] private bool blockInputDuringBump = true;
[Header("Camera Viewfinder")]
[Tooltip("The prefab to use for the camera viewfinder UI")]
[SerializeField] private GameObject viewfinderPrefab;
[Tooltip("Duration in seconds for the viewfinder to shrink")]
[SerializeField] private float viewfinderShrinkDuration = 1.5f;
[Tooltip("Speed at which the viewfinder moves toward the target")]
[SerializeField] private float viewfinderMoveSpeed = 5f;
[Tooltip("Animation curve for the shrinking effect")]
[SerializeField] private AnimationCurve viewfinderShrinkCurve = AnimationCurve.EaseInOut(0, 1, 1, 0);
[Tooltip("Padding factor to add space around the monster (1.0 = exact size, 1.2 = 20% extra)")]
[SerializeField] private float paddingFactor = 1.2f;
[Tooltip("Minimum size of the viewfinder as a percentage of screen width (0.15 = 15%)")]
[SerializeField] private float minSizePercent = 0.15f;
[Tooltip("Maximum size of the viewfinder as a percentage of screen width (0.8 = 80%)")]
[SerializeField] private float maxSizePercent = 0.8f;
[Tooltip("Starting scale of the viewfinder (relative to screen width)")]
[SerializeField] private float viewfinderStartScale = 1.0f;
[Tooltip("Final scale of the viewfinder")]
[SerializeField] private float viewfinderEndScale = 0.25f;
[Tooltip("Progress percentages at which to trigger events (0-1)")]
[SerializeField] private float[] viewfinderProgressThresholds = new float[] { 0.25f, 0.5f, 0.75f, 1.0f };
// IDivingMinigameSettings implementation - Basic Movement
public float LerpSpeed => lerpSpeed;
public float MaxOffset => maxOffset;
@@ -177,6 +209,18 @@ namespace AppleHills.Core.Settings
public float SmoothMoveSpeed => smoothMoveSpeed;
public bool BlockInputDuringBump => blockInputDuringBump;
// IDivingMinigameSettings implementation - Camera Viewfinder
public GameObject ViewfinderPrefab => viewfinderPrefab;
public float ViewfinderShrinkDuration => viewfinderShrinkDuration;
public float ViewfinderMoveSpeed => viewfinderMoveSpeed;
public AnimationCurve ViewfinderShrinkCurve => viewfinderShrinkCurve;
public float ViewfinderStartScale => viewfinderStartScale;
public float ViewfinderEndScale => viewfinderEndScale;
public float[] ViewfinderProgressThresholds => viewfinderProgressThresholds;
public float PaddingFactor => paddingFactor;
public float MaxSizePercent => maxSizePercent;
public float MinSizePercent => minSizePercent;
public override void OnValidate()
{
base.OnValidate();
@@ -238,6 +282,16 @@ namespace AppleHills.Core.Settings
damageImmunityDuration = Mathf.Max(0.1f, damageImmunityDuration);
bumpForce = Mathf.Max(0.1f, bumpForce);
smoothMoveSpeed = Mathf.Max(0.1f, smoothMoveSpeed);
// Validate camera viewfinder settings
viewfinderShrinkDuration = Mathf.Max(0.1f, viewfinderShrinkDuration);
viewfinderMoveSpeed = Mathf.Max(0.1f, viewfinderMoveSpeed);
viewfinderStartScale = Mathf.Max(0.01f, viewfinderStartScale);
viewfinderEndScale = Mathf.Max(viewfinderStartScale, viewfinderEndScale);
for (int i = 0; i < viewfinderProgressThresholds.Length; i++)
{
viewfinderProgressThresholds[i] = Mathf.Clamp01(viewfinderProgressThresholds[i]);
}
}
}
}

View File

@@ -108,5 +108,17 @@ namespace AppleHills.Core.Settings
float BumpForce { get; }
float SmoothMoveSpeed { get; }
bool BlockInputDuringBump { get; }
// Camera Viewfinder Settings
GameObject ViewfinderPrefab { get; }
float ViewfinderShrinkDuration { get; }
float ViewfinderMoveSpeed { get; }
AnimationCurve ViewfinderShrinkCurve { get; }
float ViewfinderStartScale { get; }
float ViewfinderEndScale { get; }
float[] ViewfinderProgressThresholds { get; }
float PaddingFactor { get; }
float MaxSizePercent { get; }
float MinSizePercent { get; }
}
}