From 2aee3d92ebf8259a43a286e2fa94425b18ce60cf Mon Sep 17 00:00:00 2001 From: Aditya Singh Date: Fri, 15 Dec 2023 17:09:48 +0530 Subject: [PATCH] Game Update : - Created State Machine --- Assets/Scripts/Enemy/EnemyController.cs | 6 +- .../OnePunchMan/OnePunchManController.cs | 70 ++++--------------- .../OnePunchMan/OnePunchManStateMachine.cs | 54 ++++++++++++++ .../OnePunchManStateMachine.cs.meta | 11 +++ Assets/Scripts/States.meta | 8 +++ Assets/Scripts/States/IState.cs | 14 ++++ Assets/Scripts/States/IState.cs.meta | 11 +++ Assets/Scripts/States/IdleState.cs | 27 +++++++ Assets/Scripts/States/IdleState.cs.meta | 11 +++ Assets/Scripts/States/RotatingState.cs | 33 +++++++++ Assets/Scripts/States/RotatingState.cs.meta | 11 +++ Assets/Scripts/States/ShootingState.cs | 58 +++++++++++++++ Assets/Scripts/States/ShootingState.cs.meta | 11 +++ Packages/packages-lock.json | 12 ++-- ProjectSettings/ProjectVersion.txt | 4 +- 15 files changed, 274 insertions(+), 67 deletions(-) create mode 100644 Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs create mode 100644 Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs.meta create mode 100644 Assets/Scripts/States.meta create mode 100644 Assets/Scripts/States/IState.cs create mode 100644 Assets/Scripts/States/IState.cs.meta create mode 100644 Assets/Scripts/States/IdleState.cs create mode 100644 Assets/Scripts/States/IdleState.cs.meta create mode 100644 Assets/Scripts/States/RotatingState.cs create mode 100644 Assets/Scripts/States/RotatingState.cs.meta create mode 100644 Assets/Scripts/States/ShootingState.cs create mode 100644 Assets/Scripts/States/ShootingState.cs.meta diff --git a/Assets/Scripts/Enemy/EnemyController.cs b/Assets/Scripts/Enemy/EnemyController.cs index b7a5c93b..f7713da3 100644 --- a/Assets/Scripts/Enemy/EnemyController.cs +++ b/Assets/Scripts/Enemy/EnemyController.cs @@ -14,9 +14,9 @@ public class EnemyController protected int currentHealth; protected EnemyState currentState; protected NavMeshAgent Agent => enemyView.Agent; - protected EnemyScriptableObject Data => enemyScriptableObject; - protected Quaternion Rotation => enemyView.transform.rotation; - protected Vector3 Position => enemyView.transform.position; + public EnemyScriptableObject Data => enemyScriptableObject; + public Quaternion Rotation => enemyView.transform.rotation; + public Vector3 Position => enemyView.transform.position; public EnemyController(EnemyScriptableObject enemyScriptableObject) diff --git a/Assets/Scripts/Enemy/OnePunchMan/OnePunchManController.cs b/Assets/Scripts/Enemy/OnePunchMan/OnePunchManController.cs index ecad5b56..ddca6d81 100644 --- a/Assets/Scripts/Enemy/OnePunchMan/OnePunchManController.cs +++ b/Assets/Scripts/Enemy/OnePunchMan/OnePunchManController.cs @@ -9,19 +9,23 @@ public class OnePunchManController : EnemyController { private bool isIdle; private bool isRotating; + private bool isShooting; private float idleTimer; private float shootTimer; private float targetRotation; private PlayerController target; - + private OnePunchManStateMachine stateMachine; public OnePunchManController(EnemyScriptableObject enemyScriptableObject) : base(enemyScriptableObject) { enemyView.SetController(this); - InitializeVariables(); + // InitializeVariables(); + CreateStateMachine(); + stateMachine.ChangeState(OnePunchManStates.IDLE); } + private void CreateStateMachine() => stateMachine = new OnePunchManStateMachine(this); private void InitializeVariables() { isIdle = true; @@ -36,47 +40,16 @@ public override void UpdateEnemy() if (currentState == EnemyState.DEACTIVE) return; - if(isIdle && !isRotating && !isShooting) - { - idleTimer -= Time.deltaTime; - if(idleTimer <= 0) - { - isIdle = false; - isRotating = true; - targetRotation = (Rotation.eulerAngles.y + 180) % 360; - } - } - - if(!isIdle && isRotating && !isShooting) - { - SetRotation(CalculateRotation()); - if(IsRotationComplete()) - { - isIdle = true; - isRotating = false; - ResetTimer(); - } - } - - if(!isIdle && !isRotating && isShooting) - { - Quaternion desiredRotation = CalculateRotationTowardsPlayer(); - SetRotation(RotateTowards(desiredRotation)); - - if(IsFacingPlayer(desiredRotation)) - { - shootTimer -= Time.deltaTime; - if (shootTimer <= 0) - { - shootTimer = enemyScriptableObject.RateOfFire; - Shoot(); - } - } - - } + stateMachine.Update(); + } + public override void PlayerEnteredRange(PlayerController targetToSet) + { + base.PlayerEnteredRange(targetToSet); + stateMachine.ChangeState(OnePunchManStates.SHOOTING); } + public override void PlayerExitedRange() => stateMachine.ChangeState(OnePunchManStates.IDLE); private void ResetTimer() => idleTimer = enemyScriptableObject.IdleTime; private Vector3 CalculateRotation() => Vector3.up * Mathf.MoveTowardsAngle(Rotation.eulerAngles.y, targetRotation, enemyScriptableObject.RotationSpeed * Time.deltaTime); @@ -94,21 +67,6 @@ private Quaternion CalculateRotationTowardsPlayer() private Quaternion RotateTowards(Quaternion desiredRotation) => Quaternion.LerpUnclamped(Rotation, desiredRotation, enemyScriptableObject.RotationSpeed / 30 * Time.deltaTime); - public override void PlayerEnteredRange(PlayerController targetToSet) - { - base.PlayerEnteredRange(targetToSet); - isIdle = false; - isRotating = false; - isShooting = true; - target = targetToSet; - shootTimer = 0; - } - - public override void PlayerExitedRange() - { - isIdle = true; - isRotating = false; - isShooting = false; - } + } } \ No newline at end of file diff --git a/Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs b/Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs new file mode 100644 index 00000000..0e1000a6 --- /dev/null +++ b/Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; + +namespace StatePattern.Enemy +{ + public class OnePunchManStateMachine + { + private OnePunchManController Owner; + private IState currentState; + + protected Dictionary States = new Dictionary (); + + public OnePunchManStateMachine(OnePunchManController Owner) + { + this.Owner = Owner; + CreateStates(); + SetOwner(); + } + + private void SetOwner() + { + foreach(IState state in States.Values) + { + state.Owner = Owner; + } + } + + private void CreateStates() + { + States.Add(OnePunchManStates.IDLE, new IdleState(this)); + States.Add(OnePunchManStates.ROTATING, new RotatingState(this)); + States.Add(OnePunchManStates.SHOOTING , new ShootingState(this)); + + } + + public void Update() => currentState?.Update(); + + protected void ChangeState(IState newState) + { + currentState?.OnStateExit(); + currentState = newState; + currentState?.OnStateEnter(); + } + + public void ChangeState(OnePunchManStates newState) => ChangeState(States[newState]); + } + + public enum OnePunchManStates + { + IDLE, + ROTATING, + SHOOTING + } +} \ No newline at end of file diff --git a/Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs.meta b/Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs.meta new file mode 100644 index 00000000..011b7ad1 --- /dev/null +++ b/Assets/Scripts/Enemy/OnePunchMan/OnePunchManStateMachine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f24bbaa1d8ae13f43bfd4f0bdb348688 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/States.meta b/Assets/Scripts/States.meta new file mode 100644 index 00000000..ad9a2fdf --- /dev/null +++ b/Assets/Scripts/States.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4d74fd5052e66de418fd74163f9f3ab7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/States/IState.cs b/Assets/Scripts/States/IState.cs new file mode 100644 index 00000000..ba5d9c3b --- /dev/null +++ b/Assets/Scripts/States/IState.cs @@ -0,0 +1,14 @@ +using StatePattern.Enemy; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public interface IState +{ + public OnePunchManController Owner { get; set; } + + public void OnStateEnter(); + public void Update(); + public void OnStateExit(); + +} diff --git a/Assets/Scripts/States/IState.cs.meta b/Assets/Scripts/States/IState.cs.meta new file mode 100644 index 00000000..ad2baaed --- /dev/null +++ b/Assets/Scripts/States/IState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68519825b627e3141a565c4716f7a7e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/States/IdleState.cs b/Assets/Scripts/States/IdleState.cs new file mode 100644 index 00000000..fda80bea --- /dev/null +++ b/Assets/Scripts/States/IdleState.cs @@ -0,0 +1,27 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace StatePattern.Enemy +{ + public class IdleState : IState + { + public OnePunchManController Owner { get; set; } + private OnePunchManStateMachine stateMachine; + private float timer; + + public IdleState(OnePunchManStateMachine stateMachine) => this.stateMachine = stateMachine; + + public void OnStateEnter() => ResetTimer(); + + public void Update() + { + timer -= Time.deltaTime; + if (timer <= 0) + stateMachine.ChangeState(OnePunchManStates.ROTATING); + } + + public void OnStateExit() => timer = 0; + private void ResetTimer() => timer = Owner.Data.IdleTime; + } +} \ No newline at end of file diff --git a/Assets/Scripts/States/IdleState.cs.meta b/Assets/Scripts/States/IdleState.cs.meta new file mode 100644 index 00000000..48985642 --- /dev/null +++ b/Assets/Scripts/States/IdleState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f72b247d56057494bbcbf6f1ad559c22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/States/RotatingState.cs b/Assets/Scripts/States/RotatingState.cs new file mode 100644 index 00000000..980eaeaa --- /dev/null +++ b/Assets/Scripts/States/RotatingState.cs @@ -0,0 +1,33 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using StatePattern.Main; +using StatePattern.Player; + +namespace StatePattern.Enemy +{ + public class RotatingState : IState + { + public OnePunchManController Owner { get; set; } + private OnePunchManStateMachine stateMachine; + private float targetRotation; + + public RotatingState(OnePunchManStateMachine stateMachine) => this.stateMachine = stateMachine; + + public void OnStateEnter() => targetRotation = (Owner.Rotation.eulerAngles.y + 180) % 360; + + public void Update() + { + // Calculate and set the character's rotation based on the target rotation. + Owner.SetRotation(CalculateRotation()); + if (IsRotationComplete()) + stateMachine.ChangeState(OnePunchManStates.IDLE); + } + + public void OnStateExit() => targetRotation = 0; + + private Vector3 CalculateRotation() => Vector3.up * Mathf.MoveTowardsAngle(Owner.Rotation.eulerAngles.y, targetRotation, Owner.Data.RotationSpeed * Time.deltaTime); + + private bool IsRotationComplete() => Mathf.Abs(Mathf.Abs(Owner.Rotation.eulerAngles.y) - Mathf.Abs(targetRotation)) < Owner.Data.RotationThreshold; + } +} \ No newline at end of file diff --git a/Assets/Scripts/States/RotatingState.cs.meta b/Assets/Scripts/States/RotatingState.cs.meta new file mode 100644 index 00000000..c33e8b70 --- /dev/null +++ b/Assets/Scripts/States/RotatingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ead515456bed0e4b96e2b632d62bf0f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/States/ShootingState.cs b/Assets/Scripts/States/ShootingState.cs new file mode 100644 index 00000000..1b253cbc --- /dev/null +++ b/Assets/Scripts/States/ShootingState.cs @@ -0,0 +1,58 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using StatePattern.Enemy; +using StatePattern.Main; +using StatePattern.Player; + +namespace StatePattern.Enemy +{ + public class ShootingState : IState + { + public OnePunchManController Owner { get; set; } + private OnePunchManStateMachine stateMachine; + private PlayerController target; + private float shootTimer; + + public ShootingState(OnePunchManStateMachine stateMachine) => this.stateMachine = stateMachine; + + public void OnStateEnter() + { + SetTarget(); + shootTimer = 0; + } + + public void Update() + { + Quaternion desiredRotation = CalculateRotationTowardsPlayer(); + Owner.SetRotation(RotateTowards(desiredRotation)); + + if (IsRotationComplete(desiredRotation)) + { + shootTimer -= Time.deltaTime; + if (shootTimer <= 0) + { + ResetTimer(); + Owner.Shoot(); + } + } + } + + public void OnStateExit() => target = null; + + private void SetTarget() => target = GameService.Instance.PlayerService.GetPlayer(); + + private Quaternion CalculateRotationTowardsPlayer() + { + Vector3 directionToPlayer = target.Position - Owner.Position; + directionToPlayer.y = 0f; + return Quaternion.LookRotation(directionToPlayer, Vector3.up); + } + + private Quaternion RotateTowards(Quaternion desiredRotation) => Quaternion.LerpUnclamped(Owner.Rotation, desiredRotation, Owner.Data.RotationSpeed / 30 * Time.deltaTime); + + private bool IsRotationComplete(Quaternion desiredRotation) => Quaternion.Angle(Owner.Rotation, desiredRotation) < Owner.Data.RotationThreshold; + + private void ResetTimer() => shootTimer = Owner.Data.RateOfFire; + } +} \ No newline at end of file diff --git a/Assets/Scripts/States/ShootingState.cs.meta b/Assets/Scripts/States/ShootingState.cs.meta new file mode 100644 index 00000000..9ae7d4e1 --- /dev/null +++ b/Assets/Scripts/States/ShootingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 492a8d5d7405c7345a8b8ba36531fba6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index c6bec04f..bf36f2c7 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -32,13 +32,13 @@ "depth": 0, "source": "builtin", "dependencies": { - "com.unity.ide.visualstudio": "2.0.17", - "com.unity.ide.rider": "3.0.18", + "com.unity.ide.visualstudio": "2.0.16", + "com.unity.ide.rider": "3.0.15", "com.unity.ide.vscode": "1.2.5", "com.unity.editorcoroutines": "1.0.0", - "com.unity.performance.profile-analyzer": "1.2.2", + "com.unity.performance.profile-analyzer": "1.1.1", "com.unity.test-framework": "1.1.31", - "com.unity.testtools.codecoverage": "1.2.2" + "com.unity.testtools.codecoverage": "1.0.1" } }, "com.unity.ide.rider": { @@ -67,7 +67,7 @@ "url": "https://packages.unity.com" }, "com.unity.performance.profile-analyzer": { - "version": "1.2.2", + "version": "1.1.1", "depth": 1, "source": "registry", "dependencies": {}, @@ -101,7 +101,7 @@ "url": "https://packages.unity.com" }, "com.unity.testtools.codecoverage": { - "version": "1.2.2", + "version": "1.0.1", "depth": 1, "source": "registry", "dependencies": { diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt index bca3d022..1f883d75 100644 --- a/ProjectSettings/ProjectVersion.txt +++ b/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2021.3.21f1 -m_EditorVersionWithRevision: 2021.3.21f1 (1b156197d683) +m_EditorVersion: 2021.3.10f1 +m_EditorVersionWithRevision: 2021.3.10f1 (1c7d0df0160b)