Further updates to state machines

This commit is contained in:
Michal Pikulski
2025-11-05 13:48:25 +01:00
committed by Michal Pikulski
parent 199480447e
commit b3e0f90e09
26 changed files with 2211 additions and 4383 deletions

View File

@@ -2,3 +2,4 @@ Never edit Unity's .meta files.
Always present your solution in a brief overview first.
Only implement when you have an explicit apprival to do so.
DOn't produce documentation, .md files unless explicitely asked to do so.
Never enter "" sequence into my files.

View File

@@ -1978,11 +1978,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 3484825090253933040, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3}
propertyPath: m_AnchoredPosition.x
value: 1.85
value: 0.09
objectReference: {fileID: 0}
- target: {fileID: 3484825090253933040, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3}
propertyPath: m_AnchoredPosition.y
value: 5.14
value: 3.44
objectReference: {fileID: 0}
- target: {fileID: 3484825090253933040, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3}
propertyPath: m_LocalEulerAnglesHint.x

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: 2c9ee06300474fb41b711f1c49f72d94
DefaultImporter:
guid: 97f767ded753d524086106f3c39a645f
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,17 @@
using Core.SaveLoad;
using UnityEngine;
using Pixelplacement;
public class BirdEyesBehavior : MonoBehaviour
{
private StateMachine statemachine;
private AppleMachine statemachine;
private Animator animator;
public bool correctItemIsIn;
[SerializeField] private Animator bushAnimator; // Assign in Inspector
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
statemachine = GetComponent<StateMachine>();
statemachine = GetComponent<AppleMachine>();
animator = GetComponentInChildren<Animator>();
}

View File

@@ -221,7 +221,10 @@ namespace Core.Lifecycle
{
LogDebug($"Broadcasting ManagedAwake to {managedAwakeList.Count} components");
foreach (var component in managedAwakeList)
// Create a copy to avoid collection modification during iteration
var componentsCopy = new List<ManagedBehaviour>(managedAwakeList);
foreach (var component in componentsCopy)
{
if (component == null) continue;
@@ -337,7 +340,10 @@ namespace Core.Lifecycle
ProcessBatchedSceneComponents();
}
foreach (var component in sceneReadyList)
// Create a copy to avoid collection modification during iteration
var componentsCopy = new List<ManagedBehaviour>(sceneReadyList);
foreach (var component in componentsCopy)
{
if (component == null) continue;
@@ -364,7 +370,10 @@ namespace Core.Lifecycle
{
var saveData = new Dictionary<string, string>();
foreach (var component in managedAwakeList)
// Create a copy to avoid collection modification during iteration
var componentsCopy = new List<ManagedBehaviour>(managedAwakeList);
foreach (var component in componentsCopy)
{
if (component == null || !component.AutoRegisterForSave) continue;
@@ -396,7 +405,10 @@ namespace Core.Lifecycle
{
var saveData = new Dictionary<string, string>();
foreach (var component in managedAwakeList)
// Create a copy to avoid collection modification during iteration
var componentsCopy = new List<ManagedBehaviour>(managedAwakeList);
foreach (var component in componentsCopy)
{
if (component == null || !component.AutoRegisterForSave) continue;
@@ -429,7 +441,12 @@ namespace Core.Lifecycle
if (saveData == null) return;
int restoredCount = 0;
foreach (var component in managedAwakeList)
// Create a copy to avoid collection modification during iteration
// (components might destroy themselves during restoration)
var componentsCopy = new List<ManagedBehaviour>(managedAwakeList);
foreach (var component in componentsCopy)
{
if (component == null || !component.AutoRegisterForSave) continue;
@@ -461,7 +478,11 @@ namespace Core.Lifecycle
if (saveData == null) return;
int restoredCount = 0;
foreach (var component in managedAwakeList)
// Create a copy to avoid collection modification during iteration
var componentsCopy = new List<ManagedBehaviour>(managedAwakeList);
foreach (var component in componentsCopy)
{
if (component == null || !component.AutoRegisterForSave) continue;
@@ -492,7 +513,10 @@ namespace Core.Lifecycle
{
LogDebug("Broadcasting GlobalLoadCompleted");
foreach (var component in managedAwakeList)
// Create a copy to avoid collection modification during iteration
var componentsCopy = new List<ManagedBehaviour>(managedAwakeList);
foreach (var component in componentsCopy)
{
if (component == null || !component.AutoRegisterForSave) continue;
@@ -516,7 +540,10 @@ namespace Core.Lifecycle
{
LogDebug("Broadcasting GlobalSaveStarted");
foreach (var component in managedAwakeList)
// Create a copy to avoid collection modification during iteration
var componentsCopy = new List<ManagedBehaviour>(managedAwakeList);
foreach (var component in componentsCopy)
{
if (component == null || !component.AutoRegisterForSave) continue;

View File

@@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using AppleHills.Core.Settings;
using Core.Lifecycle;
using Settings;
@@ -36,6 +36,12 @@ namespace Core
protected override void OnManagedAwake()
{
// Subscribe to SceneManagerService to enforce orientation on every scene load
if (SceneManagerService.Instance != null)
{
SceneManagerService.Instance.SceneLoadCompleted += OnSceneLoadCompleted;
}
#if UNITY_EDITOR
// When playing in the editor, manually invoke orientation check for the currently active scene
if (Application.isPlaying)
@@ -47,12 +53,18 @@ namespace Core
protected override void OnSceneReady()
{
// Handle orientation when scene is ready
// Handle orientation when scene is ready (initial scene)
// Note: This fires for the scene that just loaded, LifecycleManager tracks which scene
string sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
HandleSceneOrientation(sceneName);
}
private void OnSceneLoadCompleted(string sceneName)
{
// Enforce orientation every time a scene is loaded via SceneManagerService
HandleSceneOrientation(sceneName);
}
private void HandleSceneOrientation(string sceneName)
{
// Determine desired orientation for this scene
@@ -95,6 +107,12 @@ namespace Core
protected override void OnDestroy()
{
// Unsubscribe from events to prevent memory leaks
if (SceneManagerService.Instance != null)
{
SceneManagerService.Instance.SceneLoadCompleted -= OnSceneLoadCompleted;
}
base.OnDestroy(); // Important: call base
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using UnityEngine;
using Interactions;
namespace AppleHills.Core.Settings
{
@@ -88,5 +89,31 @@ namespace AppleHills.Core.Settings
}
return null;
}
/// <summary>
/// Finds a pickup prefab by its itemData.itemId.
/// Searches through combination rules to find result prefabs.
/// Used to spawn dynamically created items during save/load.
/// </summary>
public GameObject FindPickupPrefabByItemId(string itemId)
{
if (string.IsNullOrEmpty(itemId) || combinationRules == null)
return null;
// Search through combination rules to find a result prefab with matching itemId
foreach (var rule in combinationRules)
{
if (rule.resultPrefab != null)
{
var pickup = rule.resultPrefab.GetComponent<Pickup>();
if (pickup != null && pickup.itemData != null && pickup.itemData.itemId == itemId)
{
return rule.resultPrefab;
}
}
}
return null;
}
}
}

View File

@@ -57,6 +57,7 @@ namespace AppleHills.Core.Settings
// Methods to query item configurations
CombinationRule GetCombinationRule(PickupItemData item1, PickupItemData item2);
SlotItemConfig GetSlotItemConfig(PickupItemData slotItem);
GameObject FindPickupPrefabByItemId(string itemId);
}
/// <summary>

View File

@@ -2,6 +2,7 @@ using UnityEngine;
using Pixelplacement;
using System.Collections;
using Core;
using Core.SaveLoad;
using UnityEngine.Audio;
public class PicnicBehaviour : MonoBehaviour
@@ -12,7 +13,7 @@ public class PicnicBehaviour : MonoBehaviour
public float getFlirtyMin = 1f;
public float getFlirtyMax = 3f;
private StateMachine stateMachine;
private AppleMachine stateMachine;
private Animator animator;
[Header("The FakeChocolate to destroy!")]
@@ -32,7 +33,7 @@ public class PicnicBehaviour : MonoBehaviour
void Awake()
{
stateMachine = GetComponent<StateMachine>();
stateMachine = GetComponent<AppleMachine>();
animator = GetComponent<Animator>();
_audioSource = GetComponent<AppleAudioSource>();
}

View File

@@ -97,90 +97,7 @@ AnimationClip:
- time: 1.5833334
value: {fileID: -1414182512, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
attribute: m_Sprite
path: SoundBird
classID: 212
script: {fileID: 0}
flags: 2
- serializedVersion: 2
curve:
- time: 0
value: {fileID: -1035714051, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.033333335
value: {fileID: -740831527, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.05
value: {fileID: -648204482, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.11666667
value: {fileID: -960280295, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.13333334
value: {fileID: -1144832505, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.2
value: {fileID: -1860215682, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.25
value: {fileID: 519773293, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.26666668
value: {fileID: -1067281986, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.33333334
value: {fileID: -36811272, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.38333333
value: {fileID: -1592089404, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.41666666
value: {fileID: -1729322987, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.45
value: {fileID: -91858778, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.5
value: {fileID: -26124593, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.53333336
value: {fileID: 259088195, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.6
value: {fileID: 1746085375, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.6166667
value: {fileID: -182272111, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.68333334
value: {fileID: 1436667360, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.73333335
value: {fileID: 545467259, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.75
value: {fileID: 121392657, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.8
value: {fileID: 938631806, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.8333333
value: {fileID: 1943282875, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.8833333
value: {fileID: -1918772169, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.93333334
value: {fileID: -1252794517, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 0.96666664
value: {fileID: -927331073, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.0166667
value: {fileID: -1038168376, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.0833334
value: {fileID: 1855149249, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.1
value: {fileID: -2116798272, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.1666666
value: {fileID: 2078607702, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.1833333
value: {fileID: -633261939, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.2333333
value: {fileID: -86103801, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.2833333
value: {fileID: 1380056380, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.3166667
value: {fileID: 1797284751, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.3666667
value: {fileID: 2004539437, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.4166666
value: {fileID: 1984933759, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.45
value: {fileID: -89013944, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.5
value: {fileID: 1990407029, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.5166667
value: {fileID: 1094948637, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- time: 1.5833334
value: {fileID: -1414182512, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
attribute: m_Sprite
path: SoundBirdTakeoff/SoundBirdTakeOffAnim
path:
classID: 212
script: {fileID: 0}
flags: 2
@@ -192,16 +109,7 @@ AnimationClip:
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 1707885837
attribute: 0
script: {fileID: 0}
typeID: 212
customType: 23
isPPtrCurve: 1
isIntCurve: 0
isSerializeReferenceCurve: 0
- serializedVersion: 2
path: 631576921
path: 0
attribute: 0
script: {fileID: 0}
typeID: 212
@@ -248,44 +156,6 @@ AnimationClip:
- {fileID: 1990407029, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1094948637, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1414182512, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1035714051, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -740831527, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -648204482, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -960280295, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1144832505, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1860215682, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 519773293, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1067281986, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -36811272, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1592089404, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1729322987, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -91858778, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -26124593, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 259088195, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1746085375, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -182272111, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1436667360, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 545467259, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 121392657, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 938631806, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1943282875, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1918772169, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1252794517, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -927331073, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1038168376, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1855149249, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -2116798272, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 2078607702, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -633261939, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -86103801, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1380056380, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1797284751, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 2004539437, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1984933759, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -89013944, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1990407029, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: 1094948637, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
- {fileID: -1414182512, guid: 9d1670b18fc5fa8459596f1ddd4a4bd7, type: 3}
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}

View File

@@ -1,4 +1,5 @@
using Core;
using Core.SaveLoad;
using Pixelplacement;
using UnityEngine;
@@ -8,7 +9,7 @@ public class SoundGenerator : MonoBehaviour
[SerializeField] private Sprite exitSprite;
[SerializeField] private AudioClip enterSound;
[SerializeField] private AppleAudioSource audioSource;
[SerializeField] private StateMachine soundBirdSMRef;
[SerializeField] private AppleMachine soundBirdSMRef;
[SerializeField] private soundBird_CanFly soundbirdHearingCheck;
private bool playerInside = false;
@@ -37,7 +38,7 @@ public class SoundGenerator : MonoBehaviour
{
audioSource.audioSource.PlayOneShot(enterSound);
}
if (soundBirdSMRef != null && soundBirdSMRef.currentState.name == "SoundBird" && soundbirdHearingCheck.canFly == true)
if (soundBirdSMRef != null && soundBirdSMRef.currentState.name.ToLower().Contains("soundbird") && soundbirdHearingCheck.canFly == true)
{
soundBirdSMRef.ChangeState("SoundBirdTakeoff");

View File

@@ -1,6 +1,7 @@
using UnityEngine;
using Unity.Cinemachine;
using System.Collections;
using Core.SaveLoad;
using Pixelplacement;
public class cameraSwitcher : MonoBehaviour
@@ -12,7 +13,7 @@ public class cameraSwitcher : MonoBehaviour
[SerializeField] private float transitionDuration = 0.5f; // Duration of the transition
[SerializeField] private soundBird_FlyingBehaviour flyingBehaviour;
[SerializeField] private soundBird_TakeOffBehaviour takeOffBehaviour; // New reference
[SerializeField] private StateMachine birdStateMachine;
[SerializeField] private AppleMachine birdStateMachine;
private int playerInsideCount = 0;
private Coroutine zoomCoroutine;
@@ -32,6 +33,9 @@ public class cameraSwitcher : MonoBehaviour
private void OnTriggerExit2D(Collider2D other)
{
if (!gameObject.activeInHierarchy)
return;
if (other.CompareTag("Player"))
{
playerInsideCount--;

View File

@@ -1,3 +1,4 @@
using Core.SaveLoad;
using Pixelplacement;
using Pixelplacement.TweenSystem;
using UnityEngine;
@@ -10,7 +11,7 @@ public class soundBird_FlyingBehaviour : MonoBehaviour
public float flightDelay;
public float cooldownTime;
private StateMachine stateMachine;
private AppleMachine stateMachine;
private Animator animator;
private TweenBase objectTween;
//private Coroutine cooldownCoroutine;
@@ -21,7 +22,7 @@ public class soundBird_FlyingBehaviour : MonoBehaviour
void Awake()
{
stateMachine = GetComponentInParent<StateMachine>();
stateMachine = GetComponentInParent<AppleMachine>();
animator = GetComponentInParent<Animator>();
}

View File

@@ -1,3 +1,4 @@
using Core.SaveLoad;
using Pixelplacement;
using Pixelplacement.TweenSystem;
using UnityEngine;
@@ -9,7 +10,7 @@ public class soundBird_LandingBehaviour1 : MonoBehaviour
public float flightDuration;
public float flightDelay;
public soundBird_FlyingBehaviour flyingBehaviour;
private StateMachine stateMachine;
private AppleMachine stateMachine;
private Animator animator;
private TweenBase objectTween;
@@ -18,7 +19,7 @@ public class soundBird_LandingBehaviour1 : MonoBehaviour
void Awake()
{
stateMachine = GetComponentInParent<StateMachine>();
stateMachine = GetComponentInParent<AppleMachine>();
animator = GetComponentInParent<Animator>();
}
@@ -52,7 +53,7 @@ public class soundBird_LandingBehaviour1 : MonoBehaviour
if (stateMachine != null)
{
animator.SetBool("isScared", false);
stateMachine.ChangeState("SoundBird"); // Change to the desired state name
stateMachine.ChangeState(0); // Change to the desired state name
}
}

View File

@@ -1,3 +1,4 @@
using Core.SaveLoad;
using Pixelplacement;
using Pixelplacement.TweenSystem;
using UnityEngine;
@@ -9,7 +10,7 @@ public class soundBird_TakeOffBehaviour : MonoBehaviour
public Transform SoundBirdObject;
public float flightDuration;
public float flightDelay;
private StateMachine stateMachine;
private AppleMachine stateMachine;
private Animator animator;
private TweenBase objectTween;
public soundBird_FlyingBehaviour flyingBehaviour;
@@ -18,7 +19,7 @@ public class soundBird_TakeOffBehaviour : MonoBehaviour
void Awake()
{
stateMachine = GetComponentInParent<StateMachine>();
stateMachine = GetComponentInParent<AppleMachine>();
animator = GetComponentInParent<Animator>();
}
// Start is called once before the first execution of Update after the MonoBehaviour is created

View File

@@ -105,6 +105,9 @@ namespace Interactions
if (combinationResult == FollowerController.CombinationResult.Successful)
{
// Mark this pickup as picked up (consumed in combination) to prevent restoration
IsPickedUp = true;
// Combination succeeded - original items destroyed, result picked up by TryCombineItems
FireCombinationEvent(resultItem, heldItemData);
return true;

View File

@@ -14,8 +14,9 @@ namespace Levels
public class LevelSwitch : InteractableBase
{
public LevelSwitchData switchData;
private SpriteRenderer iconRenderer;
private IInteractionSettings interactionSettings;
private SpriteRenderer _iconRenderer;
private IInteractionSettings _interactionSettings;
private GameObject _menuObjectRef;
/// <summary>
/// Unity Awake callback. Sets up icon, interactable, and event handlers.
@@ -26,11 +27,11 @@ namespace Levels
Debug.Log($"[LevelSwitch] Awake called for {gameObject.name} in scene {gameObject.scene.name}");
if (iconRenderer == null)
iconRenderer = GetComponent<SpriteRenderer>();
if (_iconRenderer == null)
_iconRenderer = GetComponent<SpriteRenderer>();
// Initialize settings reference
interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
ApplySwitchData();
}
@@ -51,8 +52,8 @@ namespace Levels
/// </summary>
void OnValidate()
{
if (iconRenderer == null)
iconRenderer = GetComponent<SpriteRenderer>();
if (_iconRenderer == null)
_iconRenderer = GetComponent<SpriteRenderer>();
ApplySwitchData();
}
#endif
@@ -64,8 +65,8 @@ namespace Levels
{
if (switchData != null)
{
if (iconRenderer != null)
iconRenderer.sprite = switchData.mapSprite;
if (_iconRenderer != null)
_iconRenderer.sprite = switchData.mapSprite;
gameObject.name = switchData.targetLevelSceneName;
// Optionally update other fields, e.g. description
}
@@ -82,7 +83,7 @@ namespace Levels
return false;
}
var menuPrefab = interactionSettings?.LevelSwitchMenuPrefab;
var menuPrefab = _interactionSettings?.LevelSwitchMenuPrefab;
if (menuPrefab == null)
{
Debug.LogError("LevelSwitchMenu prefab not assigned in InteractionSettings!");
@@ -90,12 +91,12 @@ namespace Levels
}
// Spawn the menu overlay
var menuGo = Instantiate(menuPrefab);
var menu = menuGo.GetComponent<LevelSwitchMenu>();
_menuObjectRef = Instantiate(menuPrefab);
var menu = _menuObjectRef.GetComponent<LevelSwitchMenu>();
if (menu == null)
{
Debug.LogError("LevelSwitchMenu component missing on prefab!");
Destroy(menuGo);
Destroy(_menuObjectRef);
return false;
}

View File

@@ -106,10 +106,9 @@ namespace Minigames.DivingForPictures
public override int ManagedAwakePriority => 190;
public override bool AutoRegisterPausable => true; // Automatic GameManager registration
protected override void OnManagedAwake()
protected override void Awake()
{
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
_currentSpawnProbability = _settings?.BaseSpawnProbability ?? 0.2f;
base.Awake();
if (_instance == null)
{
@@ -119,6 +118,12 @@ namespace Minigames.DivingForPictures
{
Destroy(gameObject);
}
}
protected override void OnManagedAwake()
{
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
_currentSpawnProbability = _settings?.BaseSpawnProbability ?? 0.2f;
// Ensure any previous run state is reset when this manager awakes
_isGameOver = false;
@@ -187,6 +192,8 @@ namespace Minigames.DivingForPictures
private void Update()
{
if(_settings == null) return;
_timeSinceLastSpawn += Time.deltaTime;
// Gradually increase spawn probability over time

View File

@@ -611,12 +611,14 @@ public class FollowerController : ManagedBehaviour
newItem = Instantiate(matchingRule.resultPrefab, spawnPos, Quaternion.identity);
var resultPickup = newItem.GetComponent<Pickup>();
// Mark items as picked up before destroying (for save system)
// Mark items as picked up before disabling (for save system)
pickupA.IsPickedUp = true;
pickupB.IsPickedUp = true;
Destroy(pickupA.gameObject);
Destroy(pickupB.gameObject);
// Disable instead of destroying immediately so they can save their state
// The save system will mark them as picked up and won't restore them
pickupA.gameObject.SetActive(false);
pickupB.gameObject.SetActive(false);
// Pickup the result (don't drop it!)
TryPickupItem(newItem, resultPickup.itemData, dropItem: false);
@@ -787,7 +789,8 @@ public class FollowerController : ManagedBehaviour
/// <summary>
/// Bilateral restoration: Follower tries to find and claim the held item.
/// If pickup doesn't exist yet, it will try to claim us when it restores.
/// If pickup doesn't exist in the scene (e.g., dynamically spawned combined item),
/// spawns it from the itemData.
/// </summary>
private void TryRestoreHeldItem(string heldItemSaveId, string itemDataId)
{
@@ -797,10 +800,30 @@ public class FollowerController : ManagedBehaviour
return;
}
// Try to find the pickup immediately
// Try to find the pickup in the scene by SaveId
GameObject heldObject = ItemManager.Instance?.FindPickupBySaveId(heldItemSaveId);
if (heldObject == null)
if (heldObject == null && !string.IsNullOrEmpty(itemDataId))
{
// Item not found in scene - it might be a dynamically spawned combined item
// Try to spawn it from the itemDataId
Logging.Debug($"[FollowerController] Held item not found in scene: {heldItemSaveId}, attempting to spawn from itemId: {itemDataId}");
GameObject prefab = _interactionSettings?.FindPickupPrefabByItemId(itemDataId);
if (prefab != null)
{
// Spawn the item (inactive, since it's being held)
heldObject = Instantiate(prefab, transform.position, Quaternion.identity);
heldObject.SetActive(false);
Logging.Debug($"[FollowerController] Successfully spawned combined item: {itemDataId}");
}
else
{
Logging.Warning($"[FollowerController] Could not find prefab for itemId: {itemDataId}");
return;
}
}
else if (heldObject == null)
{
Logging.Debug($"[FollowerController] Held item not found yet: {heldItemSaveId}, waiting for pickup to restore");
return; // Pickup will find us when it restores
@@ -809,7 +832,9 @@ public class FollowerController : ManagedBehaviour
var pickup = heldObject.GetComponent<Pickup>();
if (pickup == null)
{
Logging.Warning($"[FollowerController] Found object but no Pickup component: {heldItemSaveId}");
Logging.Warning($"[FollowerController] Found/spawned object but no Pickup component: {heldItemSaveId}");
if (heldObject != null)
Destroy(heldObject);
return;
}

View File

@@ -87,15 +87,6 @@ namespace PuzzleS
}
}
void OnDisable()
{
if (_interactable != null)
{
_interactable.interactionStarted.RemoveListener(OnInteractionStarted);
_interactable.interactionComplete.RemoveListener(OnInteractionComplete);
}
}
protected override void OnDestroy()
{
base.OnDestroy();
@@ -104,6 +95,12 @@ namespace PuzzleS
{
PuzzleManager.Instance.UnregisterStepBehaviour(this);
}
if (_interactable != null)
{
_interactable.interactionStarted.RemoveListener(OnInteractionStarted);
_interactable.interactionComplete.RemoveListener(OnInteractionComplete);
}
}
/// <summary>

View File

@@ -1,18 +1,22 @@
using UnityEngine;
using Core.SaveLoad;
using Pixelplacement;
using UnityEngine;
public class AnneLiseBushBehaviour : MonoBehaviour
namespace StateMachines.Quarry.AnneLise
{
public class AnneLiseBushBehaviour : MonoBehaviour
{
private StateMachine anneLiseBushStateMachine;
private AppleMachine _anneLiseBushStateMachine;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
anneLiseBushStateMachine = GetComponent<StateMachine>();
_anneLiseBushStateMachine = GetComponent<AppleMachine>();
}
public void TakePhoto()
{
anneLiseBushStateMachine.ChangeState("TakePhoto");
_anneLiseBushStateMachine.ChangeState("TakePhoto");
}
}
}

View File

@@ -15,19 +15,16 @@ namespace StateMachines.Quarry.AnneLise
public UnityEvent animFlash;
public UnityEvent animStart;
void Start()
{
// Find references that are needed regardless of enter/restore
_playerCharacter = GameObject.FindWithTag("Player");
_playerTouchController = _playerCharacter.GetComponent<PlayerTouchController>();
}
/// <summary>
/// Called when entering this state during normal gameplay.
/// Initiates player movement and triggers photo-taking sequence.
/// </summary>
public override void OnEnterState()
{
// Find references that are needed regardless of enter/restore
_playerCharacter = GameObject.FindWithTag("Player");
_playerTouchController = _playerCharacter.GetComponent<PlayerTouchController>();
// Subscribe to player arrival event
_playerTouchController.OnArrivedAtTarget += PlayerHasArrived;

View File

@@ -46,13 +46,12 @@ namespace UI
protected override void OnManagedAwake()
{
// Component setup already done in Awake
}
protected override void OnSceneReady()
// Subscribe to scene-dependent events - must be in OnManagedAwake, not OnSceneReady
// because PauseMenu is in DontDestroyOnLoad and OnSceneReady only fires once
if (SceneManagerService.Instance != null)
{
// Subscribe to scene-dependent events
SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel;
}
// Also react to global UI hide/show events from the page controller
if (UIPageController.Instance != null)
@@ -67,6 +66,11 @@ namespace UI
Logging.Debug("[PauseMenu] Subscribed to SceneManagerService events");
}
protected override void OnSceneReady()
{
// This only fires once for DontDestroyOnLoad objects, so we handle scene loads in OnManagedAwake
}
protected override void OnDestroy()
{
base.OnDestroy();
@@ -89,17 +93,30 @@ namespace UI
/// <param name="levelName">The name of the level/scene</param>
public void SetPauseMenuByLevel(string levelName)
{
HidePauseMenu();
// TODO: Implement level-based pause menu visibility logic if needed
/*if (string.IsNullOrEmpty(levelName))
return;
// When a new scene loads, ensure pause menu is removed from UIPageController stack
// and properly hidden, regardless of pause state
if (UIPageController.Instance != null && UIPageController.Instance.CurrentPage == this)
{
UIPageController.Instance.PopPage();
}
bool isStartingLevel = levelName.ToLower().Contains("startingscene");
// Ensure pause state is cleared
if (GameManager.Instance != null && GameManager.Instance.IsPaused)
{
EndPauseSideEffects();
}
if(isStartingLevel)
HidePauseMenu(false); // Ensure menu is hidden when switching to a game level
// Hide the menu UI
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false);
if (canvasGroup != null)
{
canvasGroup.alpha = 0f;
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
}
gameObject.SetActive(false);
Logging.Debug($"[PauseMenu] Setting pause menu active: {!isStartingLevel} for scene: {levelName}");*/
Logging.Debug($"[PauseMenu] Cleaned up pause menu state for scene: {levelName}");
}
/// <summary>
@@ -246,6 +263,18 @@ namespace UI
/// </summary>
public async void ExitToAppleHills()
{
// Pop from UIPageController stack before switching scenes
if (UIPageController.Instance != null && UIPageController.Instance.CurrentPage == this)
{
UIPageController.Instance.PopPage();
}
// Ensure pause state is cleared
if (GameManager.Instance != null && GameManager.Instance.IsPaused)
{
EndPauseSideEffects();
}
// Replace with the actual scene name as set in Build Settings
var progress = new Progress<float>(p => Logging.Debug($"Loading progress: {p * 100:F0}%"));
await SceneManagerService.Instance.SwitchSceneAsync("AppleHillsOverworld", progress);

File diff suppressed because it is too large Load Diff