diff --git a/.idea/.idea.SpringJam2026/.idea/workspace.xml b/.idea/.idea.SpringJam2026/.idea/workspace.xml index 0a6a2e9..7893228 100644 --- a/.idea/.idea.SpringJam2026/.idea/workspace.xml +++ b/.idea/.idea.SpringJam2026/.idea/workspace.xml @@ -6,20 +6,11 @@ - - - + - - - - - - - - - + + diff --git a/Assets/Prefabs/UI/Tutorial.prefab b/Assets/Prefabs/UI/Tutorial.prefab new file mode 100644 index 0000000..129fd9b --- /dev/null +++ b/Assets/Prefabs/UI/Tutorial.prefab @@ -0,0 +1,57 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &5909805567631671246 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8934231714310863213} + - component: {fileID: 6093062084808708927} + m_Layer: 0 + m_Name: Tutorial + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8934231714310863213 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5909805567631671246} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3.18688, y: 0.12234, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &6093062084808708927 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5909805567631671246} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument + m_PanelSettings: {fileID: 11400000, guid: 4f01bbaf43abd294b9e7341d0530a9aa, type: 2} + m_ParentUI: {fileID: 0} + sourceAsset: {fileID: 9197481963319205126, guid: 5814a7920f5bfc44fa2409bc30e6e23f, type: 3} + m_SortingOrder: 0 + m_Position: 0 + m_WorldSpaceSizeMode: 1 + m_WorldSpaceWidth: 1920 + m_WorldSpaceHeight: 1080 + m_PivotReferenceSize: 0 + m_Pivot: 0 + m_WorldSpaceCollider: {fileID: 0} diff --git a/Assets/Prefabs/UI/Tutorial.prefab.meta b/Assets/Prefabs/UI/Tutorial.prefab.meta new file mode 100644 index 0000000..cb3549a --- /dev/null +++ b/Assets/Prefabs/UI/Tutorial.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c7e2163f311728348a296fc3229df7a3 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Bootstrap.unity b/Assets/Scenes/Bootstrap.unity index 2ec7558..ea674b5 100644 --- a/Assets/Scenes/Bootstrap.unity +++ b/Assets/Scenes/Bootstrap.unity @@ -508,6 +508,7 @@ MonoBehaviour: fruitsPrefab: {fileID: 3648719755775049102, guid: 067c711b87e00ef4d9158c92377f44a6, type: 3} deathScreenPrefab: {fileID: 6072795237519443946, guid: 439eaa80d7eac8d4db6eace5ddaf3489, type: 3} deathSound: {fileID: 8300000, guid: 9abfcb38929cf1241a742680b5fcf017, type: 3} + tutorialPrefab: {fileID: 0} --- !u!4 &1469922751 Transform: m_ObjectHideFlags: 0 diff --git a/Assets/Scenes/Game.unity b/Assets/Scenes/Game.unity index c73e1cb..8f070c3 100644 --- a/Assets/Scenes/Game.unity +++ b/Assets/Scenes/Game.unity @@ -567,6 +567,61 @@ MonoBehaviour: m_EditorClassIdentifier: Assembly-CSharp::Cam camSpeed: 20 yOffset: 1 +--- !u!1 &1131679838 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1131679840} + - component: {fileID: 1131679839} + m_Layer: 0 + m_Name: Tutorial + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1131679839 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1131679838} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument + m_PanelSettings: {fileID: 11400000, guid: 4f01bbaf43abd294b9e7341d0530a9aa, type: 2} + m_ParentUI: {fileID: 0} + sourceAsset: {fileID: 9197481963319205126, guid: 5814a7920f5bfc44fa2409bc30e6e23f, type: 3} + m_SortingOrder: 0 + m_Position: 0 + m_WorldSpaceSizeMode: 1 + m_WorldSpaceWidth: 1920 + m_WorldSpaceHeight: 1080 + m_PivotReferenceSize: 0 + m_Pivot: 0 + m_WorldSpaceCollider: {fileID: 0} +--- !u!4 &1131679840 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1131679838} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 3.18688, y: 0.12234, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1454353600 GameObject: m_ObjectHideFlags: 0 @@ -6517,3 +6572,4 @@ SceneRoots: - {fileID: 1454353602} - {fileID: 219800105} - {fileID: 1814193807} + - {fileID: 1131679840} diff --git a/Assets/Scripts/Player/Movement.cs b/Assets/Scripts/Player/Movement.cs index eb1d3e8..70b639d 100644 --- a/Assets/Scripts/Player/Movement.cs +++ b/Assets/Scripts/Player/Movement.cs @@ -11,6 +11,8 @@ namespace Player public class Movement : MonoBehaviour { public event Action OnDeath; + public event Action EnterSpring; + public event Action GetPickup; private static readonly int Spring = Animator.StringToHash("spring"); private static readonly int Grounded = Animator.StringToHash("grounded"); @@ -184,11 +186,16 @@ namespace Player HandleDeath(); return; } - + if (other.gameObject.layer == LayerMask.NameToLayer("Spring")) + { + EnterSpring?.Invoke(); _springAnimator = other.gameObject.GetComponent(); + } + if (other.gameObject.layer == LayerMask.NameToLayer("Pickup")) { + GetPickup?.Invoke(); Services.Instance.SFX.PlayOneShot(pickupSound); _airJumpCharges++; Destroy(other.gameObject); diff --git a/Assets/Scripts/State/Game/GameRunningState.cs b/Assets/Scripts/State/Game/GameRunningState.cs index a421700..2118bb8 100644 --- a/Assets/Scripts/State/Game/GameRunningState.cs +++ b/Assets/Scripts/State/Game/GameRunningState.cs @@ -11,6 +11,13 @@ namespace State.Game base.OnEnter(machine); MainStateMachine.Respawn(); MainStateMachine.PlayerMovement.OnDeath += HandleDeath; + MainStateMachine.PlayerMovement.GetPickup += HandleTutorial; + MainStateMachine.PlayerMovement.EnterSpring += HandleTutorial; + } + + private void HandleTutorial() + { + MainStateMachine.ShowTutorial(true); } private void HandleDeath() @@ -26,10 +33,14 @@ namespace State.Game // Cleanup before we remove player and fruits MainStateMachine.PlayerMovement.OnDeath -= HandleDeath; + MainStateMachine.PlayerMovement.GetPickup -= HandleTutorial; + MainStateMachine.PlayerMovement.EnterSpring -= HandleTutorial; MainStateMachine.Respawn(); // Reregister events MainStateMachine.PlayerMovement.OnDeath += HandleDeath; + MainStateMachine.PlayerMovement.GetPickup += HandleTutorial; + MainStateMachine.PlayerMovement.EnterSpring += HandleTutorial; // Wait a moment then restart the game yield return new WaitForSeconds(2f); diff --git a/Assets/Scripts/State/Game/MainStateMachine.cs b/Assets/Scripts/State/Game/MainStateMachine.cs index e20f65b..1a218cd 100644 --- a/Assets/Scripts/State/Game/MainStateMachine.cs +++ b/Assets/Scripts/State/Game/MainStateMachine.cs @@ -1,4 +1,6 @@ using System; +using System.Collections; +using Management; using Player; using UnityEngine; using UnityEngine.UIElements; @@ -19,15 +21,21 @@ namespace State.Game [SerializeField] private GameObject fruitsPrefab; [SerializeField] private GameObject deathScreenPrefab; [SerializeField] private AudioClip deathSound; + [SerializeField] private GameObject tutorialPrefab; private GameObject _playerInstance; private GameObject _fruitsInstance; private GameObject _deathScreenInstance; - + private GameObject _tutorialScreenInstance; + private bool _tutorial1Done; + private bool _tutorial2Done; + private void Awake() { _deathScreenInstance = Instantiate(deathScreenPrefab); ShowDeathScreen(false); + _tutorialScreenInstance = Instantiate(tutorialPrefab); + ShowTutorial(false); } public void Respawn() @@ -51,5 +59,46 @@ namespace State.Game { _deathScreenInstance.GetComponent().rootVisualElement.Q().visible = show; } + + public void ShowTutorial(bool show) + { + if (show) + { + if (!_tutorial1Done) + { + StartCoroutine(DelayTutorial()); + return; + } + + if (!_tutorial2Done) + { + Time.timeScale = 0; + Services.Instance.InputRouter.OnInteract += HandleClearTutorial; + _tutorial2Done = true; + _tutorialScreenInstance.GetComponent().rootVisualElement.Q("Tutorial2").style.display = DisplayStyle.Flex;; + } + } + else + { + Time.timeScale = 1; + _tutorialScreenInstance.GetComponent().rootVisualElement.Q("Tutorial1").style.display = DisplayStyle.None;Time.timeScale = 1; + _tutorialScreenInstance.GetComponent().rootVisualElement.Q("Tutorial2").style.display = DisplayStyle.None; + } + } + + private IEnumerator DelayTutorial() + { + yield return new WaitForSeconds(0.25f); + Time.timeScale = 0; + Services.Instance.InputRouter.OnInteract += HandleClearTutorial; + _tutorialScreenInstance.GetComponent().rootVisualElement.Q("Tutorial1").style.display = DisplayStyle.Flex;; + _tutorial1Done = true; + } + + private void HandleClearTutorial(bool obj) + { + Services.Instance.InputRouter.OnInteract -= HandleClearTutorial; + ShowTutorial(false); + } } } \ No newline at end of file diff --git a/Assets/UI/Tutorial.uxml b/Assets/UI/Tutorial.uxml new file mode 100644 index 0000000..2682b59 --- /dev/null +++ b/Assets/UI/Tutorial.uxml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Assets/UI/Tutorial.uxml.meta b/Assets/UI/Tutorial.uxml.meta new file mode 100644 index 0000000..1a31563 --- /dev/null +++ b/Assets/UI/Tutorial.uxml.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5814a7920f5bfc44fa2409bc30e6e23f +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}