diff --git a/Assets/GameFlowManager.cs b/Assets/GameFlowManager.cs
new file mode 100644
index 0000000..3a24fd4
--- /dev/null
+++ b/Assets/GameFlowManager.cs
@@ -0,0 +1,95 @@
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+//Could be a singleton
+public class GameFlowManager : MonoBehaviour {
+ ///
+ /// True if time is frozen (Start, Pause Menu, Dead)
+ ///
+ /// Could be renamed appropriately
+ [field: SerializeField]
+ public bool Paused { get; private set; } = true;
+ public BaseState CurrentState { get; private set; } = null!;
+ bool lastStartButton;
+
+ #region Unity Messages
+ void Awake() => CurrentState = new StartFlowState(this);
+
+ void Start() => CurrentState.EnterState();
+ #endregion
+
+ void SetPause(bool value) {
+ Paused = value;
+ Time.timeScale = value ? 0f : 1f;
+ }
+
+ #region Inputs
+ public void OnStart(InputAction.CallbackContext ctx) {
+ //feels pretty redundant ^^'
+ bool newValue = ctx.ReadValueAsButton();
+ bool wasJustPressed = !lastStartButton && newValue;
+ lastStartButton = newValue;
+
+ if (!wasJustPressed)
+ return;
+
+ if (CurrentState is StartFlowState)
+ SwitchState(new GameplayFlowState(this));
+ }
+ #endregion
+
+ #region States
+ void SwitchState(BaseState newState) {
+ CurrentState.LeaveState();
+ CurrentState = newState;
+ newState.EnterState();
+ }
+
+ abstract class GameFlowState : BaseState {
+ readonly protected GameFlowManager gameFlowManager;
+
+ protected GameFlowState(GameFlowManager gameFlowManager) {
+ this.gameFlowManager = gameFlowManager;
+ }
+ }
+
+ class StartFlowState : GameFlowState {
+ public StartFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
+
+ public override void EnterState() {
+ base.EnterState();
+
+ Debug.Log("Press Start to start...!");
+ gameFlowManager.SetPause(true);
+ }
+
+ public override void LeaveState() {
+ Debug.Log("Let the games begin!!");
+ }
+ }
+ class GameplayFlowState : GameFlowState {
+ public GameplayFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
+
+ public override void EnterState() {
+ base.EnterState();
+ gameFlowManager.SetPause(false);
+ }
+ }
+ class PauseMenuFlowState : GameFlowState {
+ public PauseMenuFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
+
+ public override void EnterState() {
+ base.EnterState();
+ gameFlowManager.SetPause(true);
+ }
+ }
+ class DeadFlowState : GameFlowState {
+ public DeadFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
+
+ public override void EnterState() {
+ base.EnterState();
+ gameFlowManager.SetPause(true);
+ }
+ }
+ #endregion
+}
\ No newline at end of file
diff --git a/Assets/GameFlowManager.cs.meta b/Assets/GameFlowManager.cs.meta
new file mode 100644
index 0000000..17ff82d
--- /dev/null
+++ b/Assets/GameFlowManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e3fecdc4a8b2cb4419ef9d03180d130d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Prefabs/Arena.prefab b/Assets/Prefabs/Arena.prefab
index 0a3af7b..6498ff6 100644
--- a/Assets/Prefabs/Arena.prefab
+++ b/Assets/Prefabs/Arena.prefab
@@ -246,7 +246,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 63e66d66543b37e419694ac22a2941fd, type: 3}
m_Name:
m_EditorClassIdentifier:
- stats: {fileID: 11400000, guid: 188711c0b201b1a45ad601ee20233b20, type: 2}
+ k__BackingField: {fileID: 11400000, guid: 188711c0b201b1a45ad601ee20233b20, type: 2}
moatCollider: {fileID: 9196727423716235687}
--- !u!1 &9196727423754814335
GameObject:
@@ -1752,6 +1752,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 72794012913ccd840a73788b90573212, type: 3}
m_Name:
m_EditorClassIdentifier:
+ gameFlowManager: {fileID: 0}
spawners:
- {x: -10, y: 10, z: 0}
- {x: 10, y: 10, z: 0}
diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity
index 85aa05c..177a0b4 100644
--- a/Assets/Scenes/SampleScene.unity
+++ b/Assets/Scenes/SampleScene.unity
@@ -211,6 +211,10 @@ PrefabInstance:
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
+ - target: {fileID: -7596782781093632548, guid: 581322f036f3ff1448d4d2ec70f295a4, type: 3}
+ propertyPath: gameFlowManager
+ value:
+ objectReference: {fileID: 1359990806}
- target: {fileID: 4164153230343464235, guid: 581322f036f3ff1448d4d2ec70f295a4, type: 3}
propertyPath: globalCamera
value:
@@ -265,6 +269,24 @@ PrefabInstance:
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 581322f036f3ff1448d4d2ec70f295a4, type: 3}
+--- !u!1 &1359990805 stripped
+GameObject:
+ m_CorrespondingSourceObject: {fileID: 9196727425507610131, guid: 581322f036f3ff1448d4d2ec70f295a4, type: 3}
+ m_PrefabInstance: {fileID: 1359990804}
+ m_PrefabAsset: {fileID: 0}
+--- !u!114 &1359990806
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1359990805}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: e3fecdc4a8b2cb4419ef9d03180d130d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ k__BackingField: 1
--- !u!114 &1464970062 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 1878107874314509256, guid: e1dac4f28fe75a547b919b7aa8240fed, type: 3}
@@ -406,20 +428,44 @@ PrefabInstance:
m_Modifications:
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.size
- value: 15
+ value: 16
objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[13].m_ActionId
value: d0405457-c534-4103-a0b6-cf113432b467
objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[14].m_ActionId
+ value: 01a06960-a379-49e3-9d58-9b7c8effcb3d
+ objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_ActionId
+ value: f7e5243b-5304-4287-a2f5-0d36470450ad
+ objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[13].m_ActionName
value: Player/SwitchMinion[/Keyboard/q,/Keyboard/e,/XInputControllerWindows/leftShoulder,/XInputControllerWindows/rightShoulder]
objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[14].m_ActionName
+ value: Player/Start[/XInputControllerWindows/start,/Keyboard/enter]
+ objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_ActionName
+ value: Player/Throw[/Keyboard/r,/XInputControllerWindows/buttonNorth]
+ objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[13].m_PersistentCalls.m_Calls.Array.size
value: 1
objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[14].m_PersistentCalls.m_Calls.Array.size
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_PersistentCalls.m_Calls.Array.size
+ value: 1
+ objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[13].m_PersistentCalls.m_Calls.Array.data[0].m_Mode
value: 0
@@ -428,6 +474,10 @@ PrefabInstance:
propertyPath: m_ActionEvents.Array.data[14].m_PersistentCalls.m_Calls.Array.data[0].m_Mode
value: 0
objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_PersistentCalls.m_Calls.Array.data[0].m_Mode
+ value: 0
+ objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[13].m_PersistentCalls.m_Calls.Array.data[0].m_Target
value:
@@ -435,6 +485,10 @@ PrefabInstance:
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[14].m_PersistentCalls.m_Calls.Array.data[0].m_Target
value:
+ objectReference: {fileID: 1359990806}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_PersistentCalls.m_Calls.Array.data[0].m_Target
+ value:
objectReference: {fileID: 330576709}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[13].m_PersistentCalls.m_Calls.Array.data[0].m_CallState
@@ -444,12 +498,20 @@ PrefabInstance:
propertyPath: m_ActionEvents.Array.data[14].m_PersistentCalls.m_Calls.Array.data[0].m_CallState
value: 2
objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_PersistentCalls.m_Calls.Array.data[0].m_CallState
+ value: 2
+ objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[13].m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
value: ChangeSelectedIcon
objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[14].m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
+ value: OnStart
+ objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
value: ToggleThrowMode
objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
@@ -458,6 +520,10 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_ActionEvents.Array.data[14].m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName
+ value: GameFlowManager, Assembly-CSharp
+ objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName
value: MinionThrower, Assembly-CSharp
objectReference: {fileID: 0}
- target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
@@ -468,6 +534,14 @@ PrefabInstance:
propertyPath: m_ActionEvents.Array.data[14].m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName
value: UnityEngine.Object, UnityEngine
objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: m_ActionEvents.Array.data[15].m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName
+ value: UnityEngine.Object, UnityEngine
+ objectReference: {fileID: 0}
+ - target: {fileID: 1214567908930553592, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: gameFlowManager
+ value:
+ objectReference: {fileID: 1359990806}
- target: {fileID: 1214567908930553593, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: m_Name
value: Vampire
@@ -524,6 +598,10 @@ PrefabInstance:
propertyPath: healthBar
value:
objectReference: {fileID: 1464970062}
+ - target: {fileID: 3126145803593047825, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
+ propertyPath: gameFlowManager
+ value:
+ objectReference: {fileID: 1359990806}
- target: {fileID: 3126145803593047825, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3}
propertyPath: k__BackingField
value: 100
diff --git a/Assets/Scripts/Arena.cs b/Assets/Scripts/Arena.cs
index 78c76bd..da1bc49 100644
--- a/Assets/Scripts/Arena.cs
+++ b/Assets/Scripts/Arena.cs
@@ -1,12 +1,20 @@
#nullable enable
using System.Collections;
+using NaughtyAttributes;
using UnityEngine;
public class Arena : MonoBehaviour {
+ [SerializeField] [Required]
+ GameFlowManager gameFlowManager = null!;
+
//TODO probably add initial direction too
- [SerializeField] Vector3[] spawners = null!;
- [SerializeField] ArenaStats stats = null!;
- [SerializeField] GameObject monsterPrefab = null!;
+ //TODO Add some kind of "MinLength(1)" attribute
+ [SerializeField]
+ Vector3[] spawners = null!;
+ [SerializeField] [Required]
+ ArenaStats stats = null!;
+ [SerializeField] [Required]
+ GameObject monsterPrefab = null!;
SafeZone safeZone = null!;
@@ -15,6 +23,9 @@ public class Arena : MonoBehaviour {
void Start() => StartCoroutine(SpawnEnemies());
void SpawnEnemy(int spawnerIndex) {
+ if (gameFlowManager.Paused)
+ return;
+
var monster = Instantiate(monsterPrefab, spawners[spawnerIndex], Quaternion.identity).GetComponent();
//TODO Replace hardcoded target with entity discovery
monster.SetTarget(FindObjectOfType().transform);
@@ -25,11 +36,10 @@ public class Arena : MonoBehaviour {
int currentSpawner = 0;
- //TODO Stop when pause/end game
while (true) {
SpawnEnemy(currentSpawner);
currentSpawner = Random.Range(0, spawners.Length);
- yield return new WaitForSeconds(stats.secondsBetweenSpawners);
+ yield return new WaitForSeconds(stats.secondsBetweenSpawners);
}
}
diff --git a/Assets/Scripts/Entity.cs b/Assets/Scripts/Entity.cs
index 617a054..b7ebc6e 100644
--- a/Assets/Scripts/Entity.cs
+++ b/Assets/Scripts/Entity.cs
@@ -1,18 +1,24 @@
using System.Collections;
using System.Collections.Generic;
+using NaughtyAttributes;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class Entity : MonoBehaviour
{
+ [SerializeField] [Required]
+ GameFlowManager gameFlowManager = null!;
+
+ [field: SerializeField] [field: Required]
+ protected EntityStats stats { get; private set; }
[field: SerializeField]public float Health {get; private set; }
+ bool isAlive = true;
public int bloodTokens = 1;
- bool isAlive = true;
- [SerializeField]public float movementSpeed{get; private set; }
- [SerializeField]public float rotSpeed {get; private set; }
+ [field: SerializeField]public float movementSpeed{get; private set; }
+ [field: SerializeField]public float rotSpeed {get; private set; }
[SerializeField]private float fov;
[SerializeField]private float attackRange;
- [SerializeField]public float attackDmg {get; private set; }
+ [field: SerializeField]public float attackDmg {get; private set; }
[SerializeField]protected float attackCooldown;
protected float attackTimer;
[SerializeField]private Transform target;
@@ -20,6 +26,7 @@ public class Entity : MonoBehaviour
private Collider atkCollider;
public Vector3 direction {get; set; }
public Rigidbody2D rb {get; private set;}
+ bool beingPushed;
void Awake() => rb = GetComponent();
@@ -28,6 +35,14 @@ public class Entity : MonoBehaviour
attackTimer = attackCooldown;
}
+ protected virtual void FixedUpdate() {
+ //TODO sqrMagnitude?
+ if (beingPushed && rb.velocity.magnitude < stats.MinVelocityWhenPushed) {
+ rb.velocity = Vector2.zero;
+ beingPushed = false;
+ }
+ }
+
protected virtual void Attack(){
}
@@ -36,11 +51,11 @@ public class Entity : MonoBehaviour
}
- protected virtual void MoveToTarget(float deltaTime){
-
- direction = Vector3.RotateTowards(direction, (target.position - transform.position), rotSpeed*deltaTime, 0.0f);
+ protected virtual void MoveToTarget(){
+ //Would be nice if we could force this to be in FixedUpdate
+ direction = Vector3.RotateTowards(direction, (target.position - transform.position), rotSpeed*Time.fixedDeltaTime, 0.0f);
if(!IsInAttackRange()){
- rb.MovePosition(transform.position + direction * movementSpeed * deltaTime);
+ rb.MovePosition(transform.position + direction * movementSpeed * Time.fixedDeltaTime);
}
}
@@ -75,4 +90,9 @@ public class Entity : MonoBehaviour
public bool IsAlive(){
return isAlive;
}
+
+ protected void AddImpulse(Vector3 impulse) {
+ beingPushed = true;
+ rb.AddForce(impulse, ForceMode2D.Impulse);
+ }
}
diff --git a/Assets/Scripts/EntityStats.cs b/Assets/Scripts/EntityStats.cs
new file mode 100644
index 0000000..654e200
--- /dev/null
+++ b/Assets/Scripts/EntityStats.cs
@@ -0,0 +1,6 @@
+using UnityEngine;
+
+public class EntityStats {
+ [field: SerializeField] [field: Min(0f)]
+ public float MinVelocityWhenPushed { get; private set; } = 5f;
+}
\ No newline at end of file
diff --git a/Assets/Scripts/EntityStats.cs.meta b/Assets/Scripts/EntityStats.cs.meta
new file mode 100644
index 0000000..0a1726f
--- /dev/null
+++ b/Assets/Scripts/EntityStats.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: f3b49b8d7dbc43dfbd074996aa811570
+timeCreated: 1648908811
\ No newline at end of file
diff --git a/Assets/Scripts/Monster.cs b/Assets/Scripts/Monster.cs
index 91d3042..0e3bf00 100644
--- a/Assets/Scripts/Monster.cs
+++ b/Assets/Scripts/Monster.cs
@@ -12,7 +12,11 @@ public class Monster : AIEntity
base.ennemyName = "Gladiator";
}
- void FixedUpdate() => MoveToTarget(Time.fixedDeltaTime);
+ protected override void FixedUpdate() {
+ base.FixedUpdate();
+
+ MoveToTarget();
+ }
// Update is called once per frame
void Update()
diff --git a/Assets/Scripts/PlayerMovement.cs b/Assets/Scripts/PlayerMovement.cs
index 7d2b652..431f005 100644
--- a/Assets/Scripts/PlayerMovement.cs
+++ b/Assets/Scripts/PlayerMovement.cs
@@ -1,37 +1,56 @@
#nullable enable
+using NaughtyAttributes;
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(PlayerInput), typeof(Rigidbody2D))]
public class PlayerMovement : MonoBehaviour {
- [SerializeField] PlayerStats stats = null!;
+ [SerializeField] [Required]
+ GameFlowManager gameFlowManager = null!;
+
+ [SerializeField] [field: Required]
+ PlayerStats stats = null!;
+
+ [field: Required]
Rigidbody2D rb = null!;
-
+
Vector2 moveDirection;
BaseState currentState = null!;
SafeZone? safeZone;
bool lastJumpButton;
- void Awake(){
+ #region Unity Messages
+
+ void Awake() {
rb = GetComponent();
currentState = new ImmobileMovementState(this);
- }
+ }
void Start() => currentState.EnterState();
void Update() {
+ if (gameFlowManager.Paused)
+ return;
+
if (currentState.UpdateState() is {} newState)
SwitchState(newState);
}
void FixedUpdate() {
+ if (gameFlowManager.Paused)
+ return;
+
if (currentState.FixedUpdateState() is {} newState)
SwitchState(newState);
}
void OnDrawGizmos() => currentState?.OnDrawGizmos();
+ #endregion
+
+ #region Inputs
+
public void OnMove(InputAction.CallbackContext ctx) {
moveDirection = ctx.ReadValue();
if (moveDirection.sqrMagnitude > 1.0f)
@@ -46,22 +65,20 @@ public class PlayerMovement : MonoBehaviour {
if (!wasJustPressed)
return;
-
- if (safeZone == null)
+
+ if (gameFlowManager.Paused || safeZone == null)
return;
if (safeZone.IsInSafeZone) {
- if (moveDirection.magnitude >= safeZone.stats.MinJumpJoystickValue)
+ if (moveDirection.magnitude >= safeZone.Stats.MinJumpJoystickValue)
SwitchState(new ExitSafeZoneMovementState(this, safeZone, moveDirection));
} else //TODO if (AngleBetween(moveDirection, toSafeZone) < 90)
SwitchState(new EnterSafeZoneMovementState(this, safeZone));
}
- void SwitchState(BaseState newState) {
- currentState.LeaveState();
- currentState = newState;
- newState.EnterState();
- }
+ #endregion
+
+ #region Rigidbody
void OnTriggerEnter2D(Collider2D other) {
if (other.GetComponent() is {} triggeredSafeZone)
@@ -85,20 +102,30 @@ public class PlayerMovement : MonoBehaviour {
rb.isKinematic = !enabled;
}
- abstract class BaseStatePlayerMovement : BaseState{
+ #endregion
+
+ #region States
+
+ void SwitchState(BaseState newState) {
+ currentState.LeaveState();
+ currentState = newState;
+ newState.EnterState();
+ }
+
+ abstract class BaseStatePlayerMovement : BaseState {
protected PlayerMovement playerMovement;
- public BaseStatePlayerMovement(PlayerMovement playerMovement){
+
+ public BaseStatePlayerMovement(PlayerMovement playerMovement) {
this.playerMovement = playerMovement;
}
}
class NormalMovementState : BaseStatePlayerMovement {
- public NormalMovementState(PlayerMovement playerMovement) : base(playerMovement){
+ public NormalMovementState(PlayerMovement playerMovement) : base(playerMovement) {}
- }
public override BaseState? FixedUpdateState() {
playerMovement.rb.velocity = (Vector3)playerMovement.moveDirection * playerMovement.stats.movementSpeed;
-
+
return null;
}
}
@@ -124,7 +151,7 @@ public class PlayerMovement : MonoBehaviour {
float currentTime = Time.time - startTime;
if (currentTime >= duration)
return Transition();
-
+
playerMovement.rb.MovePosition(Vector3.Lerp(
startPosition,
target,
@@ -140,45 +167,45 @@ public class PlayerMovement : MonoBehaviour {
class EnterSafeZoneMovementState : JumpingMovementState {
readonly SafeZone safeZone;
- public EnterSafeZoneMovementState(PlayerMovement playerMovement, SafeZone safeZone) : base(playerMovement, safeZone.stats.JumpDuration, safeZone.transform.position) {
+
+ public EnterSafeZoneMovementState(PlayerMovement playerMovement, SafeZone safeZone) : base(playerMovement, safeZone.Stats.JumpDuration, safeZone.transform.position) {
this.safeZone = safeZone;
}
public override void EnterState() {
base.EnterState();
-
+
safeZone.EnterSafeZone();
playerMovement.SetRigidbodyEnabled(false);
}
-
+
protected override BaseState Transition() => new ImmobileMovementState(playerMovement);
- protected override float ModifyLerpTime(float t) => safeZone.stats.JumpSpeedCurve.Evaluate(t);
+ protected override float ModifyLerpTime(float t) => safeZone.Stats.JumpSpeedCurve.Evaluate(t);
}
class ExitSafeZoneMovementState : JumpingMovementState {
readonly SafeZone safeZone;
- public ExitSafeZoneMovementState(PlayerMovement playerMovement, SafeZone safeZone, Vector2 direction) : base(playerMovement, safeZone.stats.JumpDuration, safeZone.GetOutsidePosition(direction)) {
+
+ public ExitSafeZoneMovementState(PlayerMovement playerMovement, SafeZone safeZone, Vector2 direction) : base(playerMovement, safeZone.Stats.JumpDuration, safeZone.GetOutsidePosition(direction)) {
this.safeZone = safeZone;
}
public override void LeaveState() {
base.EnterState();
-
+
safeZone.ExitSafeZone();
playerMovement.SetRigidbodyEnabled(true);
}
- protected override float ModifyLerpTime(float t) => safeZone.stats.JumpSpeedCurve.Evaluate(t);
+ protected override float ModifyLerpTime(float t) => safeZone.Stats.JumpSpeedCurve.Evaluate(t);
}
class ImmobileMovementState : BaseStatePlayerMovement {
- public ImmobileMovementState(PlayerMovement playerMovement) : base(playerMovement){
-
- }
+ public ImmobileMovementState(PlayerMovement playerMovement) : base(playerMovement) {}
public override void EnterState() {
base.EnterState();
-
+
if (!playerMovement.rb.isKinematic)
Debug.LogWarning("Rigidbody should probably be kinematic when immobile (when in safe zone).");
}
@@ -188,7 +215,7 @@ public class PlayerMovement : MonoBehaviour {
return;
Vector3 dropPosition = playerMovement.safeZone.GetOutsidePosition(playerMovement.moveDirection);
- bool canJump = playerMovement.moveDirection.magnitude >= playerMovement.safeZone.stats.MinJumpJoystickValue;
+ bool canJump = playerMovement.moveDirection.magnitude >= playerMovement.safeZone.Stats.MinJumpJoystickValue;
Gizmos.color = canJump ? Color.green : Color.red;
Gizmos.DrawLine(playerMovement.transform.position, dropPosition);
if (canJump)
@@ -198,4 +225,6 @@ public class PlayerMovement : MonoBehaviour {
}
#endif
}
+
+ #endregion
}
\ No newline at end of file
diff --git a/Assets/Scripts/SafeZone.cs b/Assets/Scripts/SafeZone.cs
index e2c3c03..0fe27b7 100644
--- a/Assets/Scripts/SafeZone.cs
+++ b/Assets/Scripts/SafeZone.cs
@@ -1,8 +1,10 @@
+using NaughtyAttributes;
using UnityEngine;
public class SafeZone : MonoBehaviour {
+ [field: SerializeField] [field: Required]
+ public SafeZoneStats Stats { get; private set; }
- public SafeZoneStats stats;
[SerializeField] CircleCollider2D moatCollider;
[SerializeField] GameObject globalCamera;
@@ -23,6 +25,6 @@ public class SafeZone : MonoBehaviour {
}
public Vector3 GetOutsidePosition(Vector2 direction) {
- return transform.position + (moatCollider.radius + stats.JumpOffset) * (Vector3)direction;
+ return transform.position + (moatCollider.radius + Stats.JumpOffset) * (Vector3)direction;
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/VampireEntity.cs b/Assets/Scripts/VampireEntity.cs
index a5bc04d..9be4fa5 100644
--- a/Assets/Scripts/VampireEntity.cs
+++ b/Assets/Scripts/VampireEntity.cs
@@ -1,9 +1,10 @@
-//TODO Replace with Damageable?
-
+using NaughtyAttributes;
using UnityEngine;
public class VampireEntity : Entity {
- [SerializeField] HealthBar healthBar;
+ [SerializeField] [Required]
+ HealthBar healthBar;
+ [Min(10f)]
float initialHealth;
protected override void Start() {
diff --git a/Assets/Settings/ConjureLudumDare50.inputactions b/Assets/Settings/ConjureLudumDare50.inputactions
index 4b76e6d..eba478a 100644
--- a/Assets/Settings/ConjureLudumDare50.inputactions
+++ b/Assets/Settings/ConjureLudumDare50.inputactions
@@ -41,10 +41,19 @@
"interactions": "",
"initialStateCheck": false
},
+ {
+ "name": "Start",
+ "type": "Button",
+ "id": "01a06960-a379-49e3-9d58-9b7c8effcb3d",
+ "expectedControlType": "Button",
+ "processors": "",
+ "interactions": "",
+ "initialStateCheck": false
+ },
{
"name": "Throw",
"type": "Button",
- "id": "6f870ff4-cc58-4173-855c-37192c5b63f5",
+ "id": "f7e5243b-5304-4287-a2f5-0d36470450ad",
"expectedControlType": "Button",
"processors": "",
"interactions": "",
@@ -296,7 +305,29 @@
},
{
"name": "",
- "id": "2ee1f7f0-f3f1-4e56-8612-df107e397ef8",
+ "id": "4715f838-717a-4f10-a668-05a6d761a7bc",
+ "path": "/start",
+ "interactions": "",
+ "processors": "",
+ "groups": "Gamepad",
+ "action": "Start",
+ "isComposite": false,
+ "isPartOfComposite": false
+ },
+ {
+ "name": "",
+ "id": "025fe243-6da7-4b27-9c02-f353d7a121df",
+ "path": "/enter",
+ "interactions": "",
+ "processors": "",
+ "groups": "Keyboard&Mouse",
+ "action": "Start",
+ "isComposite": false,
+ "isPartOfComposite": false
+ },
+ {
+ "name": "",
+ "id": "24e7587d-e2bf-41ae-8c97-29f00a7e8940",
"path": "/r",
"interactions": "",
"processors": "",
@@ -307,7 +338,7 @@
},
{
"name": "",
- "id": "cf5e87bb-ed2a-433c-95f7-84f0d4f35929",
+ "id": "2bf854b2-68b4-429a-bdef-806c2897ccc0",
"path": "/buttonNorth",
"interactions": "",
"processors": "",
diff --git a/Packages/manifest.json b/Packages/manifest.json
index 09feffa..de467d9 100644
--- a/Packages/manifest.json
+++ b/Packages/manifest.json
@@ -1,5 +1,6 @@
{
"dependencies": {
+ "com.dbrizov.naughtyattributes": "https://github.com/dbrizov/NaughtyAttributes.git#upm",
"com.unity.2d.animation": "5.1.1",
"com.unity.2d.pixel-perfect": "4.0.1",
"com.unity.2d.psdimporter": "4.2.0",
diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json
index 0d61740..6e15d43 100644
--- a/Packages/packages-lock.json
+++ b/Packages/packages-lock.json
@@ -1,5 +1,12 @@
{
"dependencies": {
+ "com.dbrizov.naughtyattributes": {
+ "version": "https://github.com/dbrizov/NaughtyAttributes.git#upm",
+ "depth": 0,
+ "source": "git",
+ "dependencies": {},
+ "hash": "8a8fa5a9659a6d63f196391c71e06c4286c8acd7"
+ },
"com.unity.2d.animation": {
"version": "5.1.1",
"depth": 0,