added tutorial

This commit is contained in:
Jeremy Smitherman 2026-04-25 15:29:44 -05:00
parent 5e9959ec2e
commit 2e974cef39
10 changed files with 214 additions and 15 deletions

View File

@ -6,20 +6,11 @@
<component name="ChangeListManager">
<list default="true" id="60468364-7d9c-427f-83f9-f6cd83ef8783" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.SpringJam2026/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.SpringJam2026/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Catepillar/Player.controller" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Prefabs/Catepillar/Player.controller" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Catepillar/Player.prefab" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Prefabs/Catepillar/Player.prefab" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Fruits.prefab" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Prefabs/Fruits.prefab" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scenes/Bootstrap.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/Bootstrap.unity" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scenes/Game.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/Game.unity" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player/Movement.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player/Movement.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/State/Game/MainMenuState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/State/Game/MainMenuState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/State/Game/StartGameState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/State/Game/StartGameState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Settings/UniversalRP.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Settings/UniversalRP.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Tilemaps/Forest/Forest_20.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Tilemaps/Forest/Forest_20.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/UI/MainMenu.uxml" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/MainMenu.uxml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/UniversalRenderPipelineGlobalSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UniversalRenderPipelineGlobalSettings.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ProjectSettings/Physics2DSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/ProjectSettings/Physics2DSettings.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ProjectSettings/ProjectSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/ProjectSettings/ProjectSettings.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ProjectSettings/UnityConnectSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/ProjectSettings/UnityConnectSettings.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/State/Game/GameRunningState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/State/Game/GameRunningState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/State/Game/MainStateMachine.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/State/Game/MainStateMachine.cs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -150,7 +141,7 @@
<updated>1777050991106</updated>
<workItem from="1777050993247" duration="19210000" />
<workItem from="1777098508515" duration="3575000" />
<workItem from="1777126978640" duration="15276000" />
<workItem from="1777126978640" duration="18282000" />
</task>
<servers />
</component>

View File

@ -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}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c7e2163f311728348a296fc3229df7a3
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -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}

View File

@ -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<Animator>();
}
if (other.gameObject.layer == LayerMask.NameToLayer("Pickup"))
{
GetPickup?.Invoke();
Services.Instance.SFX.PlayOneShot(pickupSound);
_airJumpCharges++;
Destroy(other.gameObject);

View File

@ -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);

View File

@ -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<UIDocument>().rootVisualElement.Q<VisualElement>().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<UIDocument>().rootVisualElement.Q<VisualElement>("Tutorial2").style.display = DisplayStyle.Flex;;
}
}
else
{
Time.timeScale = 1;
_tutorialScreenInstance.GetComponent<UIDocument>().rootVisualElement.Q<VisualElement>("Tutorial1").style.display = DisplayStyle.None;Time.timeScale = 1;
_tutorialScreenInstance.GetComponent<UIDocument>().rootVisualElement.Q<VisualElement>("Tutorial2").style.display = DisplayStyle.None;
}
}
private IEnumerator DelayTutorial()
{
yield return new WaitForSeconds(0.25f);
Time.timeScale = 0;
Services.Instance.InputRouter.OnInteract += HandleClearTutorial;
_tutorialScreenInstance.GetComponent<UIDocument>().rootVisualElement.Q<VisualElement>("Tutorial1").style.display = DisplayStyle.Flex;;
_tutorial1Done = true;
}
private void HandleClearTutorial(bool obj)
{
Services.Instance.InputRouter.OnInteract -= HandleClearTutorial;
ShowTutorial(false);
}
}
}

10
Assets/UI/Tutorial.uxml Normal file
View File

@ -0,0 +1,10 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<ui:VisualElement style="flex-grow: 1; align-items: center; justify-content: flex-start; margin-top: 200px;">
<ui:VisualElement name="Tutorial1" style="flex-grow: 0; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; background-color: rgb(0, 0, 0); display: none;">
<ui:Label text="CLICK THE LEFT MOUSE &#10;BUTTON TO LAUNCH &#10;WHEN YOU ARE OVER A SPRING" name="TutorialText1" enabled="true" style="-unity-text-align: upper-center; font-size: 20px; -unity-font-definition: url(&quot;project://database/Assets/UI/PrStart.ttf?fileID=12800000&amp;guid=d50f742a17909804e9834b7d2ff9a2d8&amp;type=3#PrStart&quot;); color: rgb(255, 107, 196); display: flex;"/>
</ui:VisualElement>
<ui:VisualElement name="Tutorial2" style="flex-grow: 0; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; background-color: rgb(0, 0, 0); display: none;">
<ui:Label text="FRUIT LETS YOU LEFT &#10;CLICK TO &#10;AIR JUMP TOWARDS &#10;YOUR MOUSE" name="TutorialText2" enabled="true" style="-unity-text-align: upper-center; font-size: 20px; -unity-font-definition: url(&quot;project://database/Assets/UI/PrStart.ttf?fileID=12800000&amp;guid=d50f742a17909804e9834b7d2ff9a2d8&amp;type=3#PrStart&quot;); color: rgb(255, 107, 196); display: flex;"/>
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 5814a7920f5bfc44fa2409bc30e6e23f
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}