diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scenes/S2 World.unity b/SheKnowsWhatYouAreToHerGame/Assets/Scenes/S2 World.unity index 8205b20..817c9e1 100644 --- a/SheKnowsWhatYouAreToHerGame/Assets/Scenes/S2 World.unity +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scenes/S2 World.unity @@ -657,13 +657,13 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 705507993} serializedVersion: 2 - m_LocalRotation: {x: 0.7111039, y: 0.10104001, z: -0.50427014, w: 0.47940975} - m_LocalPosition: {x: 2067, y: 670, z: -98} + m_LocalRotation: {x: 0.71824706, y: -0.000055872606, z: -0.56672776, w: 0.40365946} + m_LocalPosition: {x: 1869, y: 670, z: 1020} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 51.603, y: -92.931, z: -146.832} + m_LocalEulerAnglesHint: {x: 35.436, y: -92.234, z: -145.83} --- !u!114 &705507996 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/AudioManager.cs b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/AudioManager.cs index e3741a8..331572b 100644 --- a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/AudioManager.cs +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/AudioManager.cs @@ -48,7 +48,7 @@ public class AudioManager : MonoBehaviour [SerializeField] public AudioClip menuButtonHover; /// - /// function to set don't destroy on load and check for multiple instances + /// function to set doesn't destroy on load and checks for multiple instances /// private void Awake() { @@ -57,7 +57,7 @@ private void Awake() { // set this instance as the singleton instance Instance = this; - // don't destroy this instance on scene load + // don't destroy this instance on a scene load DontDestroyOnLoad(gameObject); Debug.Log("AudioManager: Awake as singleton instance"); diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/CreditsMenu.cs b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/CreditsMenu.cs index 0e4a5bc..464a2a3 100644 --- a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/CreditsMenu.cs +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/CreditsMenu.cs @@ -12,7 +12,7 @@ public class CreditsMenu : CommonMenu { /// - /// button to return to main menu + /// button to return to the main menu /// public Button ButtonReturn; @@ -33,12 +33,12 @@ public override void OnEnable() } /// - /// handles return to main menu button press, + /// handles "return to main menu" button press, /// signals the game manager appropriately /// private void OptionReturnToMainMenu() { - // return to main menu + // return to the main menu Game.SetDisplayState(GameManager.DisplayState.ScreenMainMenu); } } \ No newline at end of file diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/GameManager.cs b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/GameManager.cs index 959fbfe..dfaa8ee 100644 --- a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/GameManager.cs +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/GameManager.cs @@ -1,7 +1,7 @@ /* * author: mark joshwel * date: 29/5/2024 - * description: game manager singleton for single source of truth state management + * description: game manager singleton for a single source of truth state management */ using UnityEngine; @@ -22,7 +22,7 @@ public enum DisplayState ScreenOptionsMenu, ScreenCreditsMenu, ScreenPauseMenu, - ScreenCaughtPause, + ScreenCaughtMenu, ScreenEscapedMenu, UnassociatedState } @@ -54,7 +54,7 @@ public enum DisplayState // private Scene _previousScene; /// - /// function to set don't destroy on load and check for multiple instances + /// function to set doesn't destroy on load and checks for multiple instances /// private void Awake() { @@ -63,7 +63,7 @@ private void Awake() { // set this instance as the singleton instance Instance = this; - // don't destroy this instance on scene load + // don't destroy this instance on a scene load DontDestroyOnLoad(gameObject); Debug.Log("GameManager: Awake as singleton instance"); @@ -79,7 +79,7 @@ private void Awake() } /// - /// called when game starts, sets state to main menu + /// called when the game starts, sets state to the main menu /// // /// generic exception it couldn't verify a safe state when starting the game private void Start() @@ -155,11 +155,6 @@ private void PauseGameHelper(DisplayState incomingState) var possibleMenuObject = menu.gameObject.GetComponent(); if (possibleMenuObject == null) continue; - // Debug.Log( - // $"GameManager: PauseGameHelper - found menu '{menu}' " - // + $"with associated state {associatedState} " - // + $"against incoming state {incomingState}"); - // guard clause if the menu isn't what we're looking for if (possibleMenuObject.associatedState != incomingState) continue; @@ -230,8 +225,8 @@ public void SetDisplayState(DisplayState displayState) // set the state of the game to the incoming state _state = displayState; - // if we're transitioning into gameplay or into the main menu - // we'll need a post step to enable the correct camera + // if we're transitioning into gameplay or into the main menu, + // we'll need a post-step to enable the correct camera if (displayState is not (DisplayState.Game or DisplayState.ScreenMainMenu)) return; @@ -250,11 +245,11 @@ public void SetDisplayState(DisplayState displayState) GameObject targetCameraObject; // switch on the state to enable the correct camera - // could be an if but unity optimises switch statements anyways + // could be an if statement, but unity optimizes switch statements anyway switch (displayState) { // if we're transitioning to the main menu state, - // change camera to the main menu camera under the Menus tagged parent object + // change the camera to the main menu camera under the "Menus"-tagged parent object case DisplayState.ScreenMainMenu: Debug.Log("GameManager.SetDisplayState: targeting 'Menu Camera' camera"); targetCameraObject = GameObject.Find("Menu Camera"); diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/HerAI.cs b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/HerAI.cs new file mode 100644 index 0000000..a1c5311 --- /dev/null +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/HerAI.cs @@ -0,0 +1,197 @@ +/* + * author: mark joshwel + * date: 30/5/2024 + * description: enemy AI based off + */ + +using System; +using UnityEngine; +using UnityEngine.AI; +using Random = UnityEngine.Random; + +/// +/// AI patrolling, chasing and capturing behaviour for the enemy +/// +public class HerAI : MonoBehaviour +{ + /// + /// variable for the nav mesh agent that determines where the enemy can move + /// + public NavMeshAgent agent; + + /// + /// variable for the player's position + /// + public Transform player; + + /// + /// variables to distinguish ground and player for sensing + /// + public LayerMask whatIsGround, whatIsPlayer; + + /// + /// patrolling: variable for the next point for her to walk to + /// + public Vector3 walkPoint; + + /// + /// patrolling: variable for the range of the walk point + /// + public float walkPointRange; + + /// + /// capturing: variable for the time range between captures + /// + public float timeBetweenCaptures; + + /// + /// variable specifying the sight range of the enemy + /// + public float sightRange; + + /// + /// variable specifying the attack range of the enemy + /// + public float attackRange; + + /// + /// boolean variable for the player being in sight range + /// + public bool playerInSightRange; + + /// + /// boolean variable for the player being in attack range + /// + public bool playerInCaptureRange; + + /// + /// capturing: variable for if the enemy has attempted to capture the player + /// + private bool _attemptedCapture; + + /// + /// variable to store game manager + /// + private GameManager _game; + + /// + /// patrolling: variable to determine if the next point is set + /// + private bool _walkPointSet; + + /// + /// + private void Awake() + { + player = GameObject.Find("PlayerObj").transform; + agent = GetComponent(); + } + + /// + /// + private void Update() + { + //Check for sight and attack range + playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer); + playerInCaptureRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer); + + if (!playerInSightRange && !playerInCaptureRange) Patrolling(); + if (playerInSightRange && !playerInCaptureRange) ChasePlayer(); + if (playerInCaptureRange && playerInSightRange) CapturePlayer(); + } + + /// + /// function to find and store the game manager + /// + /// generic exception when the object is in an unplayable state + private void OnEnable() + { + // get the game manager + _game = GameObject.Find("GameManager").GetComponent(); + if (_game == null) + throw new Exception("HerAI: could not find GameManager (unreachable?)"); + } + + // /// + // /// function to destroy the enemy + // /// + // private void DestroyEnemy() + // { + // Destroy(gameObject); + // } + + /// + /// function to draw/visualize the sight and attack range of the enemy + /// + private void OnDrawGizmosSelected() + { + Gizmos.color = Color.red; + Gizmos.DrawWireSphere(transform.position, attackRange); + Gizmos.color = Color.yellow; + Gizmos.DrawWireSphere(transform.position, sightRange); + } + + /// + /// function handling patrolling behaviour + /// + private void Patrolling() + { + if (!_walkPointSet) SearchWalkPoint(); + else agent.SetDestination(walkPoint); + + // reached walk point + if ((transform.position - walkPoint).magnitude < 1f) + _walkPointSet = false; + } + + /// + /// function to look for and set the next walk point + /// + private void SearchWalkPoint() + { + //Calculate random point in range + var randomZ = Random.Range(-walkPointRange, walkPointRange); + var randomX = Random.Range(-walkPointRange, walkPointRange); + + walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, transform.position.z + randomZ); + + if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround)) + _walkPointSet = true; + } + + /// + /// function to chase the player + /// + private void ChasePlayer() + { + agent.SetDestination(player.position); + } + + /// + /// function that captures the player and signals the game manager appropriately + /// + private void CapturePlayer() + { + // // don't move the enemy + // agent.SetDestination(transform.position); + // look at me! + transform.LookAt(player); + // are we under cooldown? + if (_attemptedCapture) return; + + // signal the game manager to show the 'caught!' menu + _game.SetDisplayState(GameManager.DisplayState.ScreenCaughtMenu); + + // set the cooldown + _attemptedCapture = true; + Invoke(nameof(ResetCapture), timeBetweenCaptures); + } + + /// + /// function to reset the capture cooldown, called by Invoke() + /// + private void ResetCapture() + { + _attemptedCapture = false; + } +} \ No newline at end of file diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/HerAI.cs.meta b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/HerAI.cs.meta new file mode 100644 index 0000000..b969253 --- /dev/null +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/HerAI.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f7baa34c17324b2e9e2123e5cd3d1f07 +timeCreated: 1720167784 \ No newline at end of file diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/MainMenu.cs b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/MainMenu.cs index 07f7deb..37c0a7b 100644 --- a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/MainMenu.cs +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/MainMenu.cs @@ -13,7 +13,7 @@ public class MainMenu : CommonMenu { /// - /// button to show credits menu + /// button to show the credits menu /// public Button ButtonCredits; @@ -23,7 +23,7 @@ public class MainMenu : CommonMenu public Button ButtonExit; /// - /// button to show options menu + /// button to show the options menu /// public Button ButtonOptions; @@ -79,7 +79,7 @@ private void OptionStartGame() /// private void OptionShowCredits() { - // show credits menu + // show the credits menu Game.SetDisplayState(GameManager.DisplayState.ScreenCreditsMenu); } @@ -89,7 +89,7 @@ private void OptionShowCredits() /// private void OptionShowOptions() { - // show options menu + // show the option menu Game.SetDisplayState(GameManager.DisplayState.ScreenOptionsMenu); } @@ -100,7 +100,6 @@ private void OptionShowOptions() private void OptionQuitGame() { // quit game - // TODO: do we need to integrate this with the game manager? Debug.Log("MainMenu.OptionQuitGame: quit button pressed"); Game.Quit(); } diff --git a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/OptionsMenu.cs b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/OptionsMenu.cs index a403a9e..47d287f 100644 --- a/SheKnowsWhatYouAreToHerGame/Assets/Scripts/OptionsMenu.cs +++ b/SheKnowsWhatYouAreToHerGame/Assets/Scripts/OptionsMenu.cs @@ -12,7 +12,7 @@ public class OptionsMenu : CommonMenu { /// - /// button to return to main menu + /// button to return to the main menu /// public Button ButtonReturn; @@ -57,12 +57,12 @@ public override void OnEnable() } /// - /// handles return to main menu button press, + /// handles return to the main menu button press, /// signals the game manager appropriately /// private void OptionReturnToMainMenu() { - // return to main menu + // return to the main menu Game.SetDisplayState(GameManager.DisplayState.ScreenMainMenu); }