From 1d74f3204692bb69aabf3c57fbdf4601a31a311f Mon Sep 17 00:00:00 2001
From: miepzerino <o.skotnik@gmail.com>
Date: Sat, 16 Dec 2023 18:32:11 +0000
Subject: [PATCH] Added audio manager + sound effects

---
 Assets/Scripts/Enums/StringValueAttribute.cs             |   37 ++
 Assets/Audio/MasterAudioMixer.mixer.meta                 |    8 
 Assets/Characters/Player/Player.prefab                   |    7 
 Assets/Scripts/PlayerController.cs                       |    7 
 Assets/Scripts/Enums/AudioMixerGroupEnum.cs.meta         |   11 
 Assets/Scenes/GameplayScene.unity                        |   86 +++++
 Assets/Audio/MasterAudioMixer.mixer                      |  243 ++++++++++++++++
 Assets/Scripts/SoundManager.cs.meta                      |   11 
 Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs.meta |   11 
 Assets/Scripts/Enums/Helpers.cs.meta                     |   11 
 Assets/Scripts/Damageable.cs                             |   20 +
 Assets/Scripts/Enums/StringValueAttribute.cs.meta        |   11 
 Assets/Scripts/SoundManager.cs                           |  243 ++++++++++++++++
 Assets/Characters/Player/AC_Player.controller            |   32 +
 Assets/Scripts/Enums/AudioMixerGroupEnum.cs              |   17 +
 Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs      |   49 +++
 Assets/Scripts/Enums/Helpers.cs                          |   32 ++
 Assets/Scripts/Enums.meta                                |    8 
 18 files changed, 836 insertions(+), 8 deletions(-)

diff --git a/Assets/Audio/MasterAudioMixer.mixer b/Assets/Audio/MasterAudioMixer.mixer
new file mode 100644
index 0000000..2ec7922
--- /dev/null
+++ b/Assets/Audio/MasterAudioMixer.mixer
@@ -0,0 +1,243 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!244 &-8513871756336149352
+AudioMixerEffectController:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: 
+  m_EffectID: 9d950f7d0f013324a8463ff47433bf21
+  m_EffectName: Attenuation
+  m_MixLevel: 7955613cb23d6ec429ae99110f5bb5fc
+  m_Parameters: []
+  m_SendTarget: {fileID: 0}
+  m_EnableWetMix: 0
+  m_Bypass: 0
+--- !u!244 &-5263513002991167994
+AudioMixerEffectController:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: 
+  m_EffectID: f7d63e69a4537614f8dd11fe8ea3cc16
+  m_EffectName: Attenuation
+  m_MixLevel: a7118e64ff337724d83f14d249404d06
+  m_Parameters: []
+  m_SendTarget: {fileID: 0}
+  m_EnableWetMix: 0
+  m_Bypass: 0
+--- !u!243 &-4315284344912367673
+AudioMixerGroupController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Environment
+  m_AudioMixer: {fileID: 24100000}
+  m_GroupID: 3e8b9278278b46a41bdf1d8fe5d6cc2c
+  m_Children: []
+  m_Volume: 3da742680026095498341be62aba7b15
+  m_Pitch: e697018308d964a4281849a25190cbec
+  m_Send: 00000000000000000000000000000000
+  m_Effects:
+  - {fileID: -1705686098664301932}
+  m_UserColorIndex: 0
+  m_Mute: 0
+  m_Solo: 0
+  m_BypassEffects: 0
+--- !u!243 &-4111005898613133373
+AudioMixerGroupController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Music
+  m_AudioMixer: {fileID: 24100000}
+  m_GroupID: bc71ec81fbbfae249bece77791d1378b
+  m_Children: []
+  m_Volume: 0cf8f4e930f3cd644b56de0383f5068d
+  m_Pitch: 597d0ebfda7461249b2cb1d230639416
+  m_Send: 00000000000000000000000000000000
+  m_Effects:
+  - {fileID: -8513871756336149352}
+  m_UserColorIndex: 0
+  m_Mute: 0
+  m_Solo: 0
+  m_BypassEffects: 0
+--- !u!244 &-1705686098664301932
+AudioMixerEffectController:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: 
+  m_EffectID: 4d0c5ff9bf533d446886abcbe159740d
+  m_EffectName: Attenuation
+  m_MixLevel: b9b231bc500a5a14f9077eac88bdc073
+  m_Parameters: []
+  m_SendTarget: {fileID: 0}
+  m_EnableWetMix: 0
+  m_Bypass: 0
+--- !u!243 &-760248166169903256
+AudioMixerGroupController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Player
+  m_AudioMixer: {fileID: 24100000}
+  m_GroupID: 991abea7b53cbcd44ad2571132d50db6
+  m_Children: []
+  m_Volume: abebf7553f998c040a3107ff87d3398d
+  m_Pitch: 5bf8182e3fd3f6743b80b039afd369b6
+  m_Send: 00000000000000000000000000000000
+  m_Effects:
+  - {fileID: 2060627048271329190}
+  m_UserColorIndex: 0
+  m_Mute: 0
+  m_Solo: 0
+  m_BypassEffects: 0
+--- !u!241 &24100000
+AudioMixerController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: MasterAudioMixer
+  m_OutputGroup: {fileID: 0}
+  m_MasterGroup: {fileID: 24300002}
+  m_Snapshots:
+  - {fileID: 24500006}
+  m_StartSnapshot: {fileID: 24500006}
+  m_SuspendThreshold: -80
+  m_EnableSuspend: 1
+  m_UpdateMode: 1
+  m_ExposedParameters: []
+  m_AudioMixerGroupViews:
+  - guids:
+    - c365b9733cdfaff4998f415ef5183814
+    - f7968e4129977984fb57beb5a15e3c0e
+    - bc71ec81fbbfae249bece77791d1378b
+    - 1f6debf35b984534680149fad3697239
+    - 991abea7b53cbcd44ad2571132d50db6
+    - 3e8b9278278b46a41bdf1d8fe5d6cc2c
+    name: View
+  m_CurrentViewIndex: 0
+  m_TargetSnapshot: {fileID: 24500006}
+--- !u!243 &24300002
+AudioMixerGroupController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Master
+  m_AudioMixer: {fileID: 24100000}
+  m_GroupID: c365b9733cdfaff4998f415ef5183814
+  m_Children:
+  - {fileID: 7950700882648529567}
+  - {fileID: 1791345170463800039}
+  m_Volume: 87a7f9326b6329e4c80350b201929ef6
+  m_Pitch: c2f0d22bd60268c49a64db299cb06c0b
+  m_Send: 00000000000000000000000000000000
+  m_Effects:
+  - {fileID: 24400004}
+  m_UserColorIndex: 0
+  m_Mute: 0
+  m_Solo: 0
+  m_BypassEffects: 0
+--- !u!244 &24400004
+AudioMixerEffectController:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: 
+  m_EffectID: 435f81a61ab05c6448728ffbe8776f34
+  m_EffectName: Attenuation
+  m_MixLevel: 42508776202bf0f4ab41b4ae72e51efe
+  m_Parameters: []
+  m_SendTarget: {fileID: 0}
+  m_EnableWetMix: 0
+  m_Bypass: 0
+--- !u!245 &24500006
+AudioMixerSnapshotController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Snapshot
+  m_AudioMixer: {fileID: 24100000}
+  m_SnapshotID: 248205da814a5834aac75784592d1eb2
+  m_FloatValues: {}
+  m_TransitionOverrides: {}
+--- !u!243 &1791345170463800039
+AudioMixerGroupController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: SFX
+  m_AudioMixer: {fileID: 24100000}
+  m_GroupID: 1f6debf35b984534680149fad3697239
+  m_Children:
+  - {fileID: -760248166169903256}
+  - {fileID: -4315284344912367673}
+  m_Volume: 5dd19f7b7bc75a14b9b56b06589579d6
+  m_Pitch: 2752deaae689c434dbd1e243f3566e9e
+  m_Send: 00000000000000000000000000000000
+  m_Effects:
+  - {fileID: 3000965433200156599}
+  m_UserColorIndex: 0
+  m_Mute: 0
+  m_Solo: 0
+  m_BypassEffects: 0
+--- !u!244 &2060627048271329190
+AudioMixerEffectController:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: 
+  m_EffectID: bd6d40ad58172414b8e2976294a4a8e6
+  m_EffectName: Attenuation
+  m_MixLevel: 06e437141c91dbc4fb09c586d910f600
+  m_Parameters: []
+  m_SendTarget: {fileID: 0}
+  m_EnableWetMix: 0
+  m_Bypass: 0
+--- !u!244 &3000965433200156599
+AudioMixerEffectController:
+  m_ObjectHideFlags: 3
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: 
+  m_EffectID: 58807315126ada34fbc153cc006bf806
+  m_EffectName: Attenuation
+  m_MixLevel: b95c30e2452fa0c49821c462383bf098
+  m_Parameters: []
+  m_SendTarget: {fileID: 0}
+  m_EnableWetMix: 0
+  m_Bypass: 0
+--- !u!243 &7950700882648529567
+AudioMixerGroupController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Main Bus
+  m_AudioMixer: {fileID: 24100000}
+  m_GroupID: f7968e4129977984fb57beb5a15e3c0e
+  m_Children:
+  - {fileID: -4111005898613133373}
+  m_Volume: 0fc2ac17e3458664aa56d2866613f4ed
+  m_Pitch: 797a8a75714096d419000ad451a98b67
+  m_Send: 00000000000000000000000000000000
+  m_Effects:
+  - {fileID: -5263513002991167994}
+  m_UserColorIndex: 0
+  m_Mute: 0
+  m_Solo: 0
+  m_BypassEffects: 0
diff --git a/Assets/Audio/MasterAudioMixer.mixer.meta b/Assets/Audio/MasterAudioMixer.mixer.meta
new file mode 100644
index 0000000..c3b4859
--- /dev/null
+++ b/Assets/Audio/MasterAudioMixer.mixer.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0d8b5fa876a1f694babe962a9ef9a4a1
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 24100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Characters/Player/AC_Player.controller b/Assets/Characters/Player/AC_Player.controller
index 08682b6..032366e 100644
--- a/Assets/Characters/Player/AC_Player.controller
+++ b/Assets/Characters/Player/AC_Player.controller
@@ -38,6 +38,7 @@
   m_Transitions: []
   m_StateMachineBehaviours:
   - {fileID: -2493127153716391096}
+  - {fileID: -7480171349586238622}
   m_Position: {x: 50, y: 50, z: 0}
   m_IKOnFeet: 0
   m_WriteDefaultValues: 1
@@ -163,6 +164,23 @@
   m_MirrorParameter: 
   m_CycleOffsetParameter: 
   m_TimeParameter: 
+--- !u!114 &-7480171349586238622
+MonoBehaviour:
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: b945ea9644e2087478dac705e081e0d6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  audioClipName: PlayerDeath
+  playOnEnter: 1
+  playOnExit: 0
+  playAfterDelay: 0
+  playDelay: 0.25
 --- !u!1107 &-3544671305424738950
 AnimatorStateMachine:
   serializedVersion: 6
@@ -248,43 +266,43 @@
     m_DefaultFloat: 0
     m_DefaultInt: 0
     m_DefaultBool: 0
-    m_Controller: {fileID: 0}
+    m_Controller: {fileID: 9100000}
   - m_Name: IsFlying
     m_Type: 4
     m_DefaultFloat: 0
     m_DefaultInt: 0
     m_DefaultBool: 0
-    m_Controller: {fileID: 0}
+    m_Controller: {fileID: 9100000}
   - m_Name: IsGrounded
     m_Type: 4
     m_DefaultFloat: 0
     m_DefaultInt: 0
     m_DefaultBool: 0
-    m_Controller: {fileID: 0}
+    m_Controller: {fileID: 9100000}
   - m_Name: IsAtWall
     m_Type: 4
     m_DefaultFloat: 0
     m_DefaultInt: 0
     m_DefaultBool: 0
-    m_Controller: {fileID: 0}
+    m_Controller: {fileID: 9100000}
   - m_Name: IsAtCeiling
     m_Type: 4
     m_DefaultFloat: 0
     m_DefaultInt: 0
     m_DefaultBool: 0
-    m_Controller: {fileID: 0}
+    m_Controller: {fileID: 9100000}
   - m_Name: IsAlive
     m_Type: 4
     m_DefaultFloat: 0
     m_DefaultInt: 0
     m_DefaultBool: 1
-    m_Controller: {fileID: 0}
+    m_Controller: {fileID: 9100000}
   - m_Name: CanMove
     m_Type: 4
     m_DefaultFloat: 0
     m_DefaultInt: 0
     m_DefaultBool: 1
-    m_Controller: {fileID: 0}
+    m_Controller: {fileID: 9100000}
   m_AnimatorLayers:
   - serializedVersion: 5
     m_Name: Base Layer
diff --git a/Assets/Characters/Player/Player.prefab b/Assets/Characters/Player/Player.prefab
index 6db8cae..a58fdfa 100644
--- a/Assets/Characters/Player/Player.prefab
+++ b/Assets/Characters/Player/Player.prefab
@@ -332,6 +332,10 @@
       m_Calls: []
     m_ActionId: 3d1c6017-9298-4bde-8c6e-ad9343a4a520
     m_ActionName: UI/TrackedDeviceOrientation
+  - m_PersistentCalls:
+      m_Calls: []
+    m_ActionId: 646986b3-5de0-4aa2-ac34-b9d8ddc48d6c
+    m_ActionName: UI/Escape[/Keyboard/escape]
   m_NeverAutoSwitchControlSchemes: 0
   m_DefaultControlScheme: 
   m_DefaultActionMap: Player
@@ -454,3 +458,6 @@
   _isAlive: 1
   isInvincible: 0
   invincibilityTime: 0.25
+  hitSound: {fileID: 8300000, guid: a56db7bda08a296458a6841eff8a58c5, type: 3}
+  healSound: {fileID: 0}
+  deathSound: {fileID: 8300000, guid: 2c515a2b0290e94478bb9d181223a774, type: 3}
diff --git a/Assets/Scenes/GameplayScene.unity b/Assets/Scenes/GameplayScene.unity
index b923c6d..a44ff0c 100644
--- a/Assets/Scenes/GameplayScene.unity
+++ b/Assets/Scenes/GameplayScene.unity
@@ -1021,6 +1021,87 @@
   m_EditorClassIdentifier: 
   cam: {fileID: 519420031}
   followTarget: {fileID: 254538002}
+--- !u!1 &1133766433
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1133766435}
+  - component: {fileID: 1133766434}
+  m_Layer: 0
+  m_Name: AudioManager
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1133766434
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1133766433}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f0d274748e889294e96220fff1d8a8d7, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  audioMixer: {fileID: 24100000, guid: 0d8b5fa876a1f694babe962a9ef9a4a1, type: 2}
+  volMaster: 0.5
+  volMusic: 0.5
+  volSFX: 0.5
+  sounds:
+  - name: MusicHappy
+    clip: {fileID: 8300000, guid: 7003df9618c25a2469a053e1b6887b7e, type: 3}
+    mixerGroup: 1
+    volume: 0.016
+    pitch: 1
+    randomVolume: 0
+    randomPitch: 0
+    loop: 1
+  - name: PlayerDeathSound
+    clip: {fileID: 8300000, guid: 2c515a2b0290e94478bb9d181223a774, type: 3}
+    mixerGroup: 2
+    volume: 0.699
+    pitch: 1
+    randomVolume: 0
+    randomPitch: 0
+    loop: 0
+  - name: PlayerHit
+    clip: {fileID: 8300000, guid: a56db7bda08a296458a6841eff8a58c5, type: 3}
+    mixerGroup: 2
+    volume: 0.699
+    pitch: 1.5
+    randomVolume: 0.5
+    randomPitch: 0.5
+    loop: 0
+  - name: Money
+    clip: {fileID: 8300000, guid: 3a1b4e297698d49418effa2c18e862b7, type: 3}
+    mixerGroup: 3
+    volume: 0.699
+    pitch: 1.5
+    randomVolume: 0.5
+    randomPitch: 0.5
+    loop: 0
+--- !u!4 &1133766435
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1133766433}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: -10}
+  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 &1235149190
 GameObject:
   m_ObjectHideFlags: 0
@@ -3401,6 +3482,10 @@
     serializedVersion: 3
     m_TransformParent: {fileID: 0}
     m_Modifications:
+    - target: {fileID: 2350719025294399868, guid: c220ec455fce341408d66d880b464cad, type: 3}
+      propertyPath: healSound
+      value: 
+      objectReference: {fileID: 8300000, guid: 3a1b4e297698d49418effa2c18e862b7, type: 3}
     - target: {fileID: 2368348636056148999, guid: c220ec455fce341408d66d880b464cad, type: 3}
       propertyPath: m_LocalPosition.x
       value: 0
@@ -3464,3 +3549,4 @@
   - {fileID: 1406521045}
   - {fileID: 75655679957548990}
   - {fileID: 1409843026}
+  - {fileID: 1133766435}
diff --git a/Assets/Scripts/Damageable.cs b/Assets/Scripts/Damageable.cs
index b738468..09fa72f 100644
--- a/Assets/Scripts/Damageable.cs
+++ b/Assets/Scripts/Damageable.cs
@@ -5,9 +5,11 @@
 
 public class Damageable : MonoBehaviour
 {
+#if (UNITY_EDITOR)
     // ONLY FOR DEBUG USE
     [SerializeField]
     private bool selfDamage = false;
+#endif
     Animator animator;
 
     [SerializeField]
@@ -20,6 +22,10 @@
     private bool isInvincible = false;
     private float timeSinceHit = 0f;
     public float invincibilityTime = 0.25f;
+
+    public AudioClip hitSound;
+    public AudioClip healSound;
+    public AudioClip deathSound;
 
     public int MaxHealth
     {
@@ -42,6 +48,10 @@
             if (value <= 0)
             {
                 IsAlive = false;
+                if (deathSound != null)
+                {
+                    SoundManager.instance.PlaySoundAtPoint(gameObject, deathSound.name);
+                }
             }
         }
     }
@@ -74,10 +84,12 @@
                 timeSinceHit += Time.deltaTime;
             }
         }
+#if (UNITY_EDITOR)
         if (selfDamage)
         {
             Hit(10);
         }
+#endif
     }
 
     public void Hit(int damage)
@@ -89,6 +101,10 @@
             isInvincible = true;
 
             CharacterEvents.characterDamaged.Invoke(gameObject, actualDamageAmount);
+            if (hitSound != null)
+            {
+                SoundManager.instance.PlaySoundAtPoint(gameObject, hitSound.name);
+            }
         }
     }
 
@@ -103,6 +119,10 @@
             CharacterEvents.characterHealed.Invoke(gameObject, actualHealAmount);
 
             result = true;
+            if (healSound != null)
+            {
+                SoundManager.instance.PlaySoundAtPoint(gameObject, healSound.name);
+            }
 
         }
         return result;
diff --git a/Assets/Scripts/Enums.meta b/Assets/Scripts/Enums.meta
new file mode 100644
index 0000000..d54fb2a
--- /dev/null
+++ b/Assets/Scripts/Enums.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8a976cd2305b77e4c9f82d1db3a9ad1a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Enums/AudioMixerGroupEnum.cs b/Assets/Scripts/Enums/AudioMixerGroupEnum.cs
new file mode 100644
index 0000000..8b2ce00
--- /dev/null
+++ b/Assets/Scripts/Enums/AudioMixerGroupEnum.cs
@@ -0,0 +1,17 @@
+using System.Reflection;
+using System;
+using UnityEditor;
+using UnityEngine;
+
+namespace Assets.Scripts.Enums
+{
+    public enum AudioMixerGroupEnum
+    {
+        [StringValue("Music")]
+        Music = 1,
+        [StringValue("Player")]
+        Player = 2,
+        [StringValue("SFX")]
+        SFX = 3,
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Enums/AudioMixerGroupEnum.cs.meta b/Assets/Scripts/Enums/AudioMixerGroupEnum.cs.meta
new file mode 100644
index 0000000..5c16cee
--- /dev/null
+++ b/Assets/Scripts/Enums/AudioMixerGroupEnum.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0e2332562f878e248b485fbd0ea08f31
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Enums/Helpers.cs b/Assets/Scripts/Enums/Helpers.cs
new file mode 100644
index 0000000..0b90a21
--- /dev/null
+++ b/Assets/Scripts/Enums/Helpers.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Reflection;
+
+namespace Assets.Scripts.Enums
+{
+    internal static class Helpers
+    {
+
+        /// <summary>
+        /// Will get the string value for a given enums value, this will
+        /// only work if you assign the StringValue attribute to
+        /// the items in your enum.
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static string GetStringValue(this Enum value)
+        {
+            // Get the type
+            Type type = value.GetType();
+
+            // Get fieldinfo for this type
+            FieldInfo fieldInfo = type.GetField(value.ToString());
+
+            // Get the stringvalue attributes
+            StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
+                typeof(StringValueAttribute), false) as StringValueAttribute[];
+
+            // Return the first if there was a match.
+            return attribs.Length > 0 ? attribs[0].StringValue : null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Enums/Helpers.cs.meta b/Assets/Scripts/Enums/Helpers.cs.meta
new file mode 100644
index 0000000..1df4c91
--- /dev/null
+++ b/Assets/Scripts/Enums/Helpers.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 36acf42c21199c9499c1650c37752fa3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Enums/StringValueAttribute.cs b/Assets/Scripts/Enums/StringValueAttribute.cs
new file mode 100644
index 0000000..f3753ba
--- /dev/null
+++ b/Assets/Scripts/Enums/StringValueAttribute.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Reflection;
+using Unity.VisualScripting;
+
+namespace Assets.Scripts.Enums
+{
+    /// <summary>
+    /// This attribute is used to represent a string value
+    /// for a value in an enum.
+    /// </summary>
+    public class StringValueAttribute : Attribute
+    {
+
+        #region Properties
+
+        /// <summary>
+        /// Holds the stringvalue for a value in an enum.
+        /// </summary>
+        public string StringValue { get; protected set; }
+
+        #endregion
+
+        #region Constructor
+
+        /// <summary>
+        /// Constructor used to init a StringValue Attribute
+        /// </summary>
+        /// <param name="value"></param>
+        public StringValueAttribute(string value)
+        {
+            this.StringValue = value;
+        }
+
+        #endregion
+
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Enums/StringValueAttribute.cs.meta b/Assets/Scripts/Enums/StringValueAttribute.cs.meta
new file mode 100644
index 0000000..bd7c51d
--- /dev/null
+++ b/Assets/Scripts/Enums/StringValueAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2dee87889f574ef428ae0d06c6533f70
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/PlayerController.cs b/Assets/Scripts/PlayerController.cs
index f918a23..3072d38 100644
--- a/Assets/Scripts/PlayerController.cs
+++ b/Assets/Scripts/PlayerController.cs
@@ -159,9 +159,14 @@
         }
     }
 
+    public void TakeDamage(int damage)
+    {
+        health.Hit(damage);
+    }
+
     public void TakeFallDamage(int fallDamage)
     {
-        health.Hit(fallDamage);
+        TakeDamage(fallDamage);
     }
 
     //public void OnRun(InputAction.CallbackContext context)
diff --git a/Assets/Scripts/SoundManager.cs b/Assets/Scripts/SoundManager.cs
new file mode 100644
index 0000000..84a6a6a
--- /dev/null
+++ b/Assets/Scripts/SoundManager.cs
@@ -0,0 +1,243 @@
+using Assets.Scripts.Enums;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Audio;
+using UnityEngine.Rendering;
+using UnityEngine.UI;
+using static Unity.VisualScripting.Member;
+
+[System.Serializable]
+public class Sound
+{
+    public string name;
+    public AudioClip clip;
+    public AudioMixerGroupEnum mixerGroup;
+
+    [Range(0f, 1f)]
+    public float volume = 0.7f;
+    [Range(0.5f, 1.5f)]
+    public float pitch = 1f;
+
+    [Range(0f, 0.5f)]
+    public float randomVolume = 0.1f;
+    [Range(0f, 0.5f)]
+    public float randomPitch = 0.1f;
+
+    public bool loop = false;
+
+    private AudioSource source;
+
+    public void SetSource(AudioSource _source, AudioMixer _audioMixer)
+    {
+        source = _source;
+        source.clip = clip;
+        source.loop = loop;
+        source.outputAudioMixerGroup = _audioMixer.FindMatchingGroups(mixerGroup.GetStringValue())[0];
+    }
+
+    public void Play()
+    {
+        source.volume = volume * (1 + Random.Range(-randomVolume / 2f, randomVolume / 2f));
+        source.pitch = pitch * (1 + Random.Range(-randomPitch / 2f, randomPitch / 2f));
+        source.Play();
+    }
+
+
+    public void Stop()
+    {
+        source.Stop();
+    }
+
+    public bool IsPlaying()
+    {
+        return source.isPlaying;
+    }
+
+}
+public class SoundManager : MonoBehaviour
+{
+    public static SoundManager instance;
+    public AudioMixer audioMixer;
+
+    public float volMaster;
+    public float volMusic;
+    public float volSFX;
+
+    [SerializeField]
+    Sound[] sounds;
+
+    private void Awake()
+    {
+        if (instance != null)
+        {
+            Debug.Log("More than one SoundManager in the Scene.");
+            if (instance != this)
+            {
+                Destroy(this.gameObject);
+            }
+        }
+        else
+        {
+            instance = this;
+        }
+        for (int i = 0; i < sounds.Length; i++)
+        {
+            GameObject _go = new GameObject("Sound_" + i + "_" + sounds[i].name);
+            _go.transform.SetParent(this.transform);
+            sounds[i].SetSource(_go.AddComponent<AudioSource>(), audioMixer);
+        }
+        DontDestroyOnLoad(this);
+        PlaySound("MusicHappy");
+    }
+
+    public void PlaySound(string _name)
+    {
+        for (int i = 0; i < sounds.Length; i++)
+        {
+            if (sounds[i].name == _name)
+            {
+                sounds[i].Play();
+                return;
+            }
+        }
+
+        //no Sound with name
+        Debug.LogWarning("SoundManager: Sounds not found in list: " + _name);
+    }
+
+    public void PlaySoundAtPoint(GameObject gObject, string _name)
+    {
+        gObject.AddComponent<AudioSource>();
+        for (int i = 0; i < sounds.Length; i++)
+        {
+            if (sounds[i].name == _name)
+            {
+                gObject.GetComponent<AudioSource>().clip = sounds[i].clip;
+                gObject.GetComponent<AudioSource>().spatialBlend = 1;
+                gObject.GetComponent<AudioSource>().outputAudioMixerGroup = audioMixer.FindMatchingGroups(sounds[i].mixerGroup.GetStringValue())[0];
+                PlayClipAtPointCustom(gObject.GetComponent<AudioSource>(), gObject.transform.position, sounds[i]);
+                Destroy(gObject.GetComponent<AudioSource>());
+                return;
+            }
+        }
+
+        //no Sound with name
+        Debug.LogWarning("SoundManager: Sounds not found in list: " + _name);
+    }
+
+    private static AudioSource PlayClipAtPointCustom(AudioSource audioSource, Vector3 pos, Sound sound)
+    {
+        audioSource.volume = sound.volume * (1 + Random.Range(-sound.randomVolume / 2f, sound.randomVolume / 2f));
+        audioSource.pitch = sound.pitch * (1 + Random.Range(-sound.randomPitch / 2f, sound.randomPitch / 2f));
+        GameObject tempGO = new GameObject("TempAudio"); // create the temp object
+        tempGO.transform.position = pos; // set its position
+        AudioSource tempASource = tempGO.AddComponent<AudioSource>(); // add an audio source
+        tempASource.clip = audioSource.clip;
+        tempASource.outputAudioMixerGroup = audioSource.outputAudioMixerGroup;
+        tempASource.mute = audioSource.mute;
+        tempASource.bypassEffects = audioSource.bypassEffects;
+        tempASource.bypassListenerEffects = audioSource.bypassListenerEffects;
+        tempASource.bypassReverbZones = audioSource.bypassReverbZones;
+        tempASource.playOnAwake = audioSource.playOnAwake;
+        tempASource.loop = audioSource.loop;
+        tempASource.priority = audioSource.priority;
+        tempASource.volume = audioSource.volume;
+        tempASource.pitch = audioSource.pitch;
+        tempASource.panStereo = audioSource.panStereo;
+        tempASource.spatialBlend = audioSource.spatialBlend;
+        tempASource.reverbZoneMix = audioSource.reverbZoneMix;
+        tempASource.dopplerLevel = audioSource.dopplerLevel;
+        tempASource.rolloffMode = audioSource.rolloffMode;
+        tempASource.minDistance = audioSource.minDistance;
+        tempASource.spread = audioSource.spread;
+        tempASource.maxDistance = audioSource.maxDistance;
+        // set other aSource properties here, if desired
+        tempASource.Play(); // start the sound
+        MonoBehaviour.Destroy(tempGO, tempASource.clip.length); // destroy object after clip duration (this will not account for whether it is set to loop)
+        return tempASource; // return the AudioSource reference
+    }
+    public void ChangeMasterVolume(float _volume)
+    {
+        volMaster = _volume;
+        audioMixer.SetFloat("masterVol", 20f * Mathf.Log10(_volume));
+    }
+
+    public void ChangeMusicVolume(float _volume)
+    {
+        volMusic = _volume;
+        audioMixer.SetFloat("musicVol", 20f * Mathf.Log10(_volume));
+    }
+
+    public void ChangeSfxVolume(float _volume)
+    {
+        volSFX = _volume;
+        audioMixer.SetFloat("sfxVol", 20f * Mathf.Log10(_volume));
+    }
+
+    public void ChangeMusic(string _name)
+    {
+        for (int i = 0; i < sounds.Length; i++)
+        {
+            if (sounds[i].mixerGroup == AudioMixerGroupEnum.Music && sounds[i].IsPlaying())
+            {
+                sounds[i].Stop();
+                PlaySound(_name);
+                return;
+            }
+        }
+        Debug.Log("No music was playing!");
+        PlaySound(_name);
+        return;
+    }
+
+    public void SaveAudioSettings()
+    {
+        PlayerPrefs.SetFloat("pVolMaster", volMaster);
+        PlayerPrefs.SetFloat("pVolMusic", volMusic);
+        PlayerPrefs.SetFloat("pVolSFX", volSFX);
+
+        Debug.Log("Saved Options");
+    }
+
+    public void LoadAudioSettings()
+    {
+        GameObject tempGO = new GameObject("TempSlider");
+
+        if (PlayerPrefs.HasKey("pVolMaster") == false)
+        {
+            PlayerPrefs.SetFloat("pVolMaster", 0.5f);
+        }
+
+        if (PlayerPrefs.HasKey("pVolMusic") == false)
+        {
+            PlayerPrefs.SetFloat("pVolMusic", 0.5f);
+        }
+
+        if (PlayerPrefs.HasKey("pVolSFX") == false)
+        {
+            PlayerPrefs.SetFloat("pVolSFX", 0.5f);
+        }
+
+        volMaster = PlayerPrefs.GetFloat("pVolMaster");
+        volMusic = PlayerPrefs.GetFloat("pVolMusic");
+        volSFX = PlayerPrefs.GetFloat("pVolSFX");
+
+        if (GameObject.Find("SliderVolume") == false)
+        {
+            ChangeMasterVolume(volMaster);
+            ChangeSfxVolume(volSFX);
+            ChangeMusicVolume(volMusic);
+            return;
+        }
+
+        GameObject.Find("SliderVolume").GetComponent<Slider>().value = volMaster;
+        ChangeMasterVolume(volMaster);
+        GameObject.Find("SliderSFX").GetComponent<Slider>().value = volSFX;
+        ChangeSfxVolume(volSFX);
+        GameObject.Find("SliderMusic").GetComponent<Slider>().value = volMusic;
+        ChangeMusicVolume(volMusic);
+
+    }
+
+}
diff --git a/Assets/Scripts/SoundManager.cs.meta b/Assets/Scripts/SoundManager.cs.meta
new file mode 100644
index 0000000..9e777ef
--- /dev/null
+++ b/Assets/Scripts/SoundManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f0d274748e889294e96220fff1d8a8d7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs b/Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs
new file mode 100644
index 0000000..b032804
--- /dev/null
+++ b/Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs
@@ -0,0 +1,49 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class PlayOneShotBehaviour : StateMachineBehaviour
+{
+    public string audioClipName;
+    public bool playOnEnter = true, playOnExit = false, playAfterDelay = false;
+
+    // Delayed sound timer
+    public float playDelay = 0.25f;
+    private float timeSinceEntered = 0f;
+    private bool hasDelayedSoundPlayed = false;
+
+    //OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
+    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
+    {
+        if (playOnEnter)
+        {
+            SoundManager.instance.PlaySoundAtPoint(animator.gameObject, audioClipName);
+        }
+    }
+
+    //OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
+    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
+    {
+        if (playAfterDelay && !hasDelayedSoundPlayed)
+        {
+            timeSinceEntered += Time.deltaTime;
+
+            if (timeSinceEntered > playDelay)
+            {
+                SoundManager.instance.PlaySoundAtPoint(animator.gameObject, audioClipName);
+                hasDelayedSoundPlayed = true;
+            }
+        }
+
+    }
+
+    //OnStateExit is called when a transition ends and the state machine finishes evaluating this state
+    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
+    {
+        if (playOnExit)
+        {
+            SoundManager.instance.PlaySoundAtPoint(animator.gameObject, audioClipName);
+        }
+
+    }
+}
diff --git a/Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs.meta b/Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs.meta
new file mode 100644
index 0000000..8b8e765
--- /dev/null
+++ b/Assets/Scripts/StateMachine/PlayOneShotBehaviour.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b945ea9644e2087478dac705e081e0d6
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

--
Gitblit v1.9.3