diff --git a/Assets/Prefabs/Arena.prefab b/Assets/Prefabs/Arena.prefab index 0090b60..1edf323 100644 --- a/Assets/Prefabs/Arena.prefab +++ b/Assets/Prefabs/Arena.prefab @@ -1756,12 +1756,18 @@ MonoBehaviour: m_EditorClassIdentifier: gameFlowManager: {fileID: 1359990806} spawners: - - {x: -10, y: 10, z: 0} - - {x: 10, y: 10, z: 0} - - {x: -17.75, y: 0, z: 0} - - {x: 17.75, y: 0, z: 0} - - {x: -10, y: -10, z: 0} - - {x: 10, y: -10, z: 0} + - position: {x: -10, y: 10} + direction: {x: 0, y: -1} + - position: {x: 10, y: 10} + direction: {x: 0, y: -1} + - position: {x: -17.75, y: 0} + direction: {x: 1, y: 0} + - position: {x: 17.75, y: 0} + direction: {x: -1, y: 0} + - position: {x: -10, y: -10} + direction: {x: 0, y: 1} + - position: {x: 10, y: -10} + direction: {x: 0, y: 1} stats: {fileID: 11400000, guid: fe319ad8c9a37b84e8b45268c913d54c, type: 2} entityPrefab: {fileID: 197677485360569561, guid: b25a487d193f24049b6a791adf592b2e, type: 3} --- !u!114 &1359990806 @@ -1776,4 +1782,5 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: e3fecdc4a8b2cb4419ef9d03180d130d, type: 3} m_Name: m_EditorClassIdentifier: + gameTimer: {fileID: 0} k__BackingField: 1 diff --git a/Assets/Scenes/JasonScene.unity b/Assets/Scenes/JasonScene.unity index f4f0a0a..a81fe42 100644 --- a/Assets/Scenes/JasonScene.unity +++ b/Assets/Scenes/JasonScene.unity @@ -222,10 +222,10 @@ PrefabInstance: m_Modification: m_TransformParent: {fileID: 0} m_Modifications: - - target: {fileID: -7596782781093632548, guid: 581322f036f3ff1448d4d2ec70f295a4, type: 3} - propertyPath: gameFlowManager + - target: {fileID: 1359990806, guid: 581322f036f3ff1448d4d2ec70f295a4, type: 3} + propertyPath: gameTimer value: - objectReference: {fileID: 1359990806} + objectReference: {fileID: 344214379} - target: {fileID: 4164153230343464235, guid: 581322f036f3ff1448d4d2ec70f295a4, type: 3} propertyPath: globalCamera value: @@ -280,25 +280,17 @@ 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} +--- !u!114 &1359990809 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 1359990806, 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_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: e3fecdc4a8b2cb4419ef9d03180d130d, type: 3} m_Name: m_EditorClassIdentifier: - gameTimer: {fileID: 344214379} - k__BackingField: 1 --- !u!114 &1464970062 stripped MonoBehaviour: m_CorrespondingSourceObject: {fileID: 1878107874314509256, guid: e1dac4f28fe75a547b919b7aa8240fed, type: 3} @@ -513,11 +505,11 @@ 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} + objectReference: {fileID: 1359990809} - 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: 1359990806} + objectReference: {fileID: 1359990809} - target: {fileID: 1214567908930553477, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3} propertyPath: m_ActionEvents.Array.data[16].m_PersistentCalls.m_Calls.Array.data[0].m_Target value: @@ -589,7 +581,7 @@ PrefabInstance: - target: {fileID: 1214567908930553592, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3} propertyPath: gameFlowManager value: - objectReference: {fileID: 1359990806} + objectReference: {fileID: 1359990809} - target: {fileID: 1214567908930553593, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3} propertyPath: m_Name value: Vampire @@ -642,6 +634,10 @@ PrefabInstance: propertyPath: m_SortingOrder value: 0 objectReference: {fileID: 0} + - target: {fileID: 1967503440015794769, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3} + propertyPath: gameFlowManager + value: + objectReference: {fileID: 1359990809} - target: {fileID: 3126145803593047825, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3} propertyPath: healthBar value: @@ -653,7 +649,7 @@ PrefabInstance: - target: {fileID: 3126145803593047825, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3} propertyPath: gameFlowManager value: - objectReference: {fileID: 1359990806} + objectReference: {fileID: 1359990809} - target: {fileID: 3126145803593047825, guid: 3e0aae8cda56aef44af9598dc5471020, type: 3} propertyPath: k__BackingField value: 100 diff --git a/Assets/Scripts/AI Stats.asset b/Assets/Scripts/AI Stats.asset index 33007e2..28ef788 100644 --- a/Assets/Scripts/AI Stats.asset +++ b/Assets/Scripts/AI Stats.asset @@ -26,3 +26,28 @@ MonoBehaviour: - {x: 14, y: 0, z: 0} - {x: 14, y: 0, z: 0} - {x: 14, y: 0, z: 0} + k__BackingField: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 2.4414444 + outSlope: 2.4414444 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0.036708858 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: -0.042344622 + outSlope: -0.042344622 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.05569625 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + k__BackingField: 0.15 diff --git a/Assets/Scripts/AIEntity.cs b/Assets/Scripts/AIEntity.cs index 13079ec..2439739 100644 --- a/Assets/Scripts/AIEntity.cs +++ b/Assets/Scripts/AIEntity.cs @@ -6,16 +6,14 @@ using UnityEngine.Serialization; public class AIEntity : Entity { - [FormerlySerializedAs("stats")] [SerializeField] AIStats AIStats = null!; + [FormerlySerializedAs("stats")] [SerializeField] + public AIStats AIStats = null!; BaseState currentState = null!; public string[] enemies {get; protected set; } - override protected void Awake(){ - base.Awake(); - currentState = new FindTargetState(this); - } override protected void Start(){ base.Start(); + currentState = CreateInitialState(); currentState.EnterState(); } @@ -37,6 +35,8 @@ public class AIEntity : Entity newState.EnterState(); } + protected virtual BaseState CreateInitialState() => new FindTargetState(this); + //Looks into enemy name list to see if the other is targetable virtual protected bool IsTargetable(Entity other){ foreach (string name in enemies){ @@ -48,75 +48,14 @@ public class AIEntity : Entity return false; } - abstract class BaseStateAI : BaseState{ + protected abstract class BaseStateAI : BaseState{ protected AIEntity entity; public BaseStateAI(AIEntity entity){ this.entity = entity; } } - /*//Basically a copy of JumpingMovementState - class NonPhysicThrownState : BaseStateAI { - readonly Vector3 target; - - Vector3 startPosition; - float duration; - float startTime; - - public NonPhysicThrownState(AIEntity entity, Vector3 target) : base(entity) { - this.target = target; - } - - public override void EnterState() { - base.EnterState(); - - duration = entity.AIStats.ThrownDurationPerMeter * Vector3.Distance(entity.transform.position, target); - startPosition = entity.transform.position; - startTime = Time.time; - entity.rb.SetEnabled(false); - } - - public override void LeaveState() { - base.LeaveState(); - entity.rb.SetEnabled(true); - } - - public override BaseState? FixedUpdateState() { - float currentTime = Time.time - startTime; - if (currentTime >= duration) - return new FindTargetState(entity); - - entity.rb.MovePosition(Vector3.Lerp( - startPosition, - target, - entity.AIStats.ThrownCurve.Evaluate(currentTime / duration) - )); - - return null; - } - }*/ - - class ThrownState : BaseStateAI { - public ThrownState(AIEntity entity) : base(entity) {} - - public override void EnterState() { - base.EnterState(); - - entity.rb.SetEnabled(false); - } - - public override void LeaveState() { - base.LeaveState(); - entity.rb.SetEnabled(true); - } - - public override BaseState? FixedUpdateState() - => entity.rb.velocity.magnitude < entity.stats.MinVelocityWhenThrown - ? new FindTargetState(entity) - : null; - } - - class SeekState : BaseStateAI{ + protected class SeekState : BaseStateAI{ public SeekState(AIEntity entity) : base(entity){ } @@ -152,7 +91,7 @@ public class AIEntity : Entity } } - class FindTargetState : BaseStateAI{ + protected class FindTargetState : BaseStateAI{ float closeEnough; Vector3 roamPosition; public FindTargetState(AIEntity entity) : base(entity){ @@ -199,7 +138,7 @@ public class AIEntity : Entity } - class AttackState : BaseStateAI{ + protected class AttackState : BaseStateAI{ public AttackState(AIEntity entity) : base(entity){ } @@ -234,7 +173,7 @@ public class AIEntity : Entity } } - class DeadState : BaseStateAI{ + protected class DeadState : BaseStateAI{ public DeadState(AIEntity entity) : base(entity){ Debug.Log("Dead!"); } diff --git a/Assets/Scripts/AIStats.cs b/Assets/Scripts/AIStats.cs index ab0756a..92e133b 100644 --- a/Assets/Scripts/AIStats.cs +++ b/Assets/Scripts/AIStats.cs @@ -12,8 +12,8 @@ public class AIStats : ScriptableObject { } [field: SerializeField] - public AnimationCurve ThrownCurve { get; } + public AnimationCurve ThrownCurve { get; private set; } [field: SerializeField] - public float ThrownDurationPerMeter { get; } + public float ThrownDurationPerMeter { get; private set; } } \ No newline at end of file diff --git a/Assets/Scripts/Arena Stats.asset b/Assets/Scripts/Arena Stats.asset index d412c84..caed1c1 100644 --- a/Assets/Scripts/Arena Stats.asset +++ b/Assets/Scripts/Arena Stats.asset @@ -12,4 +12,4 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 8de175900b604adb984b49af64538a07, type: 3} m_Name: Arena Stats m_EditorClassIdentifier: - secondsBetweenSpawners: 3 + secondsBetweenSpawners: 8 diff --git a/Assets/Scripts/Arena.cs b/Assets/Scripts/Arena.cs index 6ec7ed2..995c266 100644 --- a/Assets/Scripts/Arena.cs +++ b/Assets/Scripts/Arena.cs @@ -1,16 +1,24 @@ #nullable enable +using System; using System.Collections; using NaughtyAttributes; using UnityEngine; +using Random = UnityEngine.Random; public class Arena : MonoBehaviour { + [Serializable] + struct GladiatorEntrance { + public Vector2 position; + public Vector2 direction; + } + [SerializeField] [Required] GameFlowManager gameFlowManager = null!; //TODO probably add initial direction too //TODO Add some kind of "MinLength(1)" attribute [SerializeField] - Vector3[] spawners = null!; + GladiatorEntrance[] spawners = null!; [SerializeField] [Required] ArenaStats stats = null!; [SerializeField] [Required] @@ -26,8 +34,9 @@ public class Arena : MonoBehaviour { if (gameFlowManager.Paused) return; - var entity = Instantiate(entityPrefab, spawners[spawnerIndex], Quaternion.identity).GetComponent(); - entity.gameFlowManager = (gameFlowManager); + var entity = Instantiate(entityPrefab, spawners[spawnerIndex].position, Quaternion.identity).GetComponent(); + entity.direction = spawners[spawnerIndex].direction; + entity.gameFlowManager = gameFlowManager; } IEnumerator SpawnEnemies() { @@ -45,8 +54,10 @@ public class Arena : MonoBehaviour { #if UNITY_EDITOR void OnDrawGizmosSelected() { Gizmos.color = Color.blue; - foreach (Vector3 spawner in spawners) - Gizmos.DrawWireCube(spawner, Vector3.one); + foreach (GladiatorEntrance entrance in spawners) { + Gizmos.DrawWireCube(entrance.position, Vector3.one); + Gizmos.DrawLine(entrance.position, entrance.position + entrance.direction); + } } #endif } \ No newline at end of file diff --git a/Assets/Scripts/Entity.cs b/Assets/Scripts/Entity.cs index 5c679ec..c734c34 100644 --- a/Assets/Scripts/Entity.cs +++ b/Assets/Scripts/Entity.cs @@ -11,7 +11,7 @@ public class Entity : MonoBehaviour { [field: SerializeField] [field: Required] - protected EntityStats stats { get; private set; } + public EntityStats stats { get; private set; } [field: SerializeField] public float Health { get; private set; } [Min(10f)] protected float initialHealth; @@ -36,7 +36,9 @@ public class Entity : MonoBehaviour { virtual protected void Awake() => rb = GetComponent(); protected virtual void Start() { - direction = new Vector3(1, 0, 0); + if (direction == Vector3.zero && !(this is VampireEntity)) + Debug.LogWarning("Entity had null direction."); + attackTimer = attackCooldown; initialHealth = Health; if (halo != null) { diff --git a/Assets/Scripts/MinionThrower.cs b/Assets/Scripts/MinionThrower.cs index 759ce59..e6dacdc 100644 --- a/Assets/Scripts/MinionThrower.cs +++ b/Assets/Scripts/MinionThrower.cs @@ -1,9 +1,13 @@ +#nullable enable using System.Collections; using System.Collections.Generic; +using NaughtyAttributes; using UnityEngine; using UnityEngine.InputSystem; public class MinionThrower : MonoBehaviour { + [SerializeField] [Required] + GameFlowManager gameFlowManager = null!; public Entity[] minionPrefabs; public GameObject aimArrow; @@ -12,11 +16,13 @@ public class MinionThrower : MonoBehaviour { Vector2 throwDirection = Vector2.right; MinionBar minionBar; VampireEntity vampireEntity; + PlayerMovement movement; float currentCooldownTimer; float currentInitialCooldown; void Awake() { vampireEntity = GetComponent(); + movement = GetComponent(); minionBar = FindObjectOfType(); aimArrow.SetActive(false); } @@ -35,6 +41,9 @@ public class MinionThrower : MonoBehaviour { } public void ToggleThrowMode(InputAction.CallbackContext context) { + if (gameFlowManager.Paused) + return; + if (context.performed) { isInThrowMode = true; aimArrow.SetActive(true); @@ -65,9 +74,15 @@ public class MinionThrower : MonoBehaviour { currentCooldownTimer = currentInitialCooldown; minionBar.UpdateReload(currentCooldownTimer / currentInitialCooldown); - Entity newMinion = Instantiate(minionBar.GetCurrentMinion().gameObject, transform.position + new Vector3(throwDirection.x, throwDirection.y, 0f) * 1f, Quaternion.identity).GetComponent(); + var newMinion = Instantiate(minionBar.GetCurrentMinion().gameObject, transform.position + new Vector3(throwDirection.x, throwDirection.y, 0f) * 1f, Quaternion.identity) + .GetComponent(); + if (movement.GetSafeZone() is {} safeZone) { + newMinion.thrownFromSafeZone = true; + newMinion.thrownTargetPosition = safeZone.GetOutsidePosition(throwDirection); + } + + newMinion.direction = throwDirection; newMinion.gameFlowManager = vampireEntity.gameFlowManager; - // Apply throw force } } diff --git a/Assets/Scripts/Monster.cs b/Assets/Scripts/Monster.cs index d3b0c10..0f0568d 100644 --- a/Assets/Scripts/Monster.cs +++ b/Assets/Scripts/Monster.cs @@ -1,9 +1,10 @@ -using System.Collections; -using System.Collections.Generic; +#nullable enable using UnityEngine; -public class Monster : AIEntity -{ +public class Monster : AIEntity { + public bool thrownFromSafeZone; + public Vector3 thrownTargetPosition; + // Start is called before the first frame update override protected void Start() { @@ -12,4 +13,69 @@ public class Monster : AIEntity base.enemies = new string[]{"Gladiator"}; } + protected override BaseState CreateInitialState() + => thrownFromSafeZone + ? (BaseStateAI)new NonPhysicThrownState(this, thrownTargetPosition) + : new ThrownState(this); + + //Basically a copy of JumpingMovementState + protected class NonPhysicThrownState : BaseStateAI { + readonly Vector3 target; + + Vector3 startPosition; + float duration; + float startTime; + + public NonPhysicThrownState(AIEntity entity, Vector3 target) : base(entity) { + this.target = target; + } + + public override void EnterState() { + base.EnterState(); + + duration = entity.AIStats.ThrownDurationPerMeter * Vector3.Distance(entity.transform.position, target); + startPosition = entity.transform.position; + startTime = Time.time; + entity.rb.SetEnabled(false); + } + + public override void LeaveState() { + base.LeaveState(); + entity.rb.SetEnabled(true); + } + + public override BaseState? FixedUpdateState() { + float currentTime = Time.time - startTime; + if (currentTime >= duration) + return new FindTargetState(entity); + + entity.rb.MovePosition(Vector3.Lerp( + startPosition, + target, + entity.AIStats.ThrownCurve.Evaluate(currentTime / duration) + )); + + return null; + } + } + + protected class ThrownState : BaseStateAI { + public ThrownState(AIEntity entity) : base(entity) {} + + public override void EnterState() { + base.EnterState(); + + entity.rb.SetEnabled(false); + } + + public override void LeaveState() { + base.LeaveState(); + entity.rb.SetEnabled(true); + } + + public override BaseState? FixedUpdateState() + => entity.rb.velocity.magnitude < entity.stats.MinVelocityWhenThrown + ? new FindTargetState(entity) + : null; + } } diff --git a/Assets/Scripts/PlayerMovement.cs b/Assets/Scripts/PlayerMovement.cs index a1a5eb2..eed2519 100644 --- a/Assets/Scripts/PlayerMovement.cs +++ b/Assets/Scripts/PlayerMovement.cs @@ -49,6 +49,10 @@ public class PlayerMovement : MonoBehaviour { #endregion + public SafeZone? GetSafeZone() { + return safeZone; + } + #region Inputs public void OnMove(InputAction.CallbackContext ctx) {