diff --git a/Assets/Prefabs/Enemies/Dice_Enemy_0.5.prefab b/Assets/Prefabs/Enemies/Dice_Enemy_0.5.prefab new file mode 100644 index 0000000..ee27750 --- /dev/null +++ b/Assets/Prefabs/Enemies/Dice_Enemy_0.5.prefab @@ -0,0 +1,157 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &7594820331705313156 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalScale.x + value: 20 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalScale.y + value: 20 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalScale.z + value: 20 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalPosition.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalRotation.w + value: 0.3044174 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalRotation.x + value: -0.23603721 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalRotation.y + value: 0.6382242 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalRotation.z + value: 0.66654813 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -8679921383154817045, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_ConstrainProportionsScale + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 919132149155446097, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_Name + value: Dice_Enemy_0.5 + objectReference: {fileID: 0} + - target: {fileID: 919132149155446097, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + propertyPath: m_TagString + value: Enemy + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + insertIndex: -1 + addedObject: {fileID: 2706656759585124322} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + insertIndex: -1 + addedObject: {fileID: 8062664184138368341} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + insertIndex: -1 + addedObject: {fileID: 7925268694638970133} + m_SourcePrefab: {fileID: 100100000, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} +--- !u!1 &7324912429315955413 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: f1ba87c0234acfa4da251bb1bf3fe963, type: 3} + m_PrefabInstance: {fileID: 7594820331705313156} + m_PrefabAsset: {fileID: 0} +--- !u!135 &2706656759585124322 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7324912429315955413} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Radius: 0.034196023 + m_Center: {x: 0.000000018626451, y: -0.000000013038518, z: 0.000000014901165} +--- !u!195 &8062664184138368341 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7324912429315955413} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.034196038 + m_Speed: 2 + m_Acceleration: 8 + avoidancePriority: 50 + m_AngularSpeed: 500 + m_StoppingDistance: 0 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 0.06668757 + m_BaseOffset: 0.033343785 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 4 +--- !u!114 &7925268694638970133 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7324912429315955413} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 53554f0e5c5ef3146a592d5dfe75e390, type: 3} + m_Name: + m_EditorClassIdentifier: + hp: 100 + prefab: {fileID: 0} + detectionRadius: 5 + patrollRadius: 3 + damage: 5 + attackRate: 1 + attackRadius: 1 + target: {fileID: 0} + currentState: 0 diff --git a/Assets/Prefabs/Enemies/Dice_Enemy_0.5.prefab.meta b/Assets/Prefabs/Enemies/Dice_Enemy_0.5.prefab.meta new file mode 100644 index 0000000..4d307c8 --- /dev/null +++ b/Assets/Prefabs/Enemies/Dice_Enemy_0.5.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: af1b1b28060a1304cad2fe043638ef87 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Game/GameController.prefab b/Assets/Prefabs/Game/GameController.prefab index 51a29e8..1781bdf 100644 --- a/Assets/Prefabs/Game/GameController.prefab +++ b/Assets/Prefabs/Game/GameController.prefab @@ -64,5 +64,6 @@ MonoBehaviour: enemies: - prefab: {fileID: 3602081654026665026, guid: 7ab59219438e4a241affd5e9441d9d9f, type: 3} weight: 1 - - prefab: {fileID: 3602081654026665026, guid: 7ab59219438e4a241affd5e9441d9d9f, type: 3} + - prefab: {fileID: 7324912429315955413, guid: af1b1b28060a1304cad2fe043638ef87, type: 3} weight: 1 + startEnemiesNumber: 2 diff --git a/Assets/Scripts/Enemies/MeleeEnemy.cs b/Assets/Scripts/Enemies/MeleeEnemy.cs index c181502..a199be8 100644 --- a/Assets/Scripts/Enemies/MeleeEnemy.cs +++ b/Assets/Scripts/Enemies/MeleeEnemy.cs @@ -3,7 +3,6 @@ using UnityEngine.AI; public class MeleeEnemy : Enemy { - public float speed = 1f; public float detectionRadius = 5f; public float patrollRadius = 3f; public float damage = 5f; @@ -14,6 +13,7 @@ public class MeleeEnemy : Enemy [SerializeField] MeleeEnemyState currentState = MeleeEnemyState.Patrolling; Vector3 patrollingTarget; NavMeshAgent navMeshAgent; + float currentDelay = 0; void Start() { target = FindFirstObjectByType(); @@ -24,22 +24,52 @@ public class MeleeEnemy : Enemy void Update() { switch (currentState) { case MeleeEnemyState.Patrolling: - Vector3 vectorToTarget = (target.transform.position - transform.position).normalized; - bool canSee = false; - if (Physics.Raycast(transform.position, vectorToTarget, out RaycastHit hit, detectionRadius)) { - if (hit.transform.CompareTag("Player")) canSee = true; - } - if (canSee) currentState = MeleeEnemyState.Pursuing; + if (CanSeeTarget()) currentState = MeleeEnemyState.Pursuing; else { - if (Vector3.Distance(transform.position, patrollingTarget) <= 0.1f) patrollingTarget = GetPatrollingTarget(); + if (Vector3.Distance(transform.position - new Vector3(0, navMeshAgent.baseOffset * transform.localScale.y), navMeshAgent.destination) <= 0.1f) patrollingTarget = GetPatrollingTarget(); navMeshAgent.destination = patrollingTarget; } break; + case MeleeEnemyState.Pursuing: + if (!CanSeeTarget()) currentState = MeleeEnemyState.Patrolling; + navMeshAgent.destination = target.transform.position; + if (Vector3.Distance(transform.position, target.transform.position) <= attackRadius) currentState = MeleeEnemyState.Attacking; + break; + case MeleeEnemyState.Attacking: + navMeshAgent.ResetPath(); + if (Vector3.Distance(transform.position, target.transform.position) >= attackRadius) currentState = CanSeeTarget() ? MeleeEnemyState.Pursuing : MeleeEnemyState.Patrolling; + else if (currentDelay >= 1 / attackRate) { + target.DealDamage(damage); + currentDelay = 0; + } + break; + } + if (attackRate != 0) { + if (currentState == MeleeEnemyState.Attacking) currentDelay = Mathf.Clamp(currentDelay += Time.deltaTime, 0, 1 / attackRate); + else currentDelay = 0; } } Vector3 GetPatrollingTarget() { - return Vector3.zero; + NavMeshPath path = new(); + while (true) { + Vector2 circle = Random.insideUnitCircle * patrollRadius; + Vector3 maybeDestination = transform.position + new Vector3(circle.x, 0, circle.y); + NavMesh.CalculatePath(transform.position, maybeDestination, NavMesh.AllAreas, path); + if (path.status == NavMeshPathStatus.PathComplete) return maybeDestination; + if (path.status != NavMeshPathStatus.PathInvalid) break; + } + Vector3 destination = path.corners[^1]; + destination.y = transform.position.y; + return destination; + } + + bool CanSeeTarget() {Vector3 vectorToTarget = (target.transform.position - transform.position).normalized; + bool canSee = false; + if (Physics.Raycast(transform.position, vectorToTarget, out RaycastHit hit, detectionRadius)) { + if (hit.transform.CompareTag("Player")) canSee = true; + } + return canSee; } } diff --git a/Assets/Scripts/Game/GameController.cs b/Assets/Scripts/Game/GameController.cs index 7869d08..bfab080 100644 --- a/Assets/Scripts/Game/GameController.cs +++ b/Assets/Scripts/Game/GameController.cs @@ -11,6 +11,7 @@ public class GameController : MonoBehaviour public string deploySceneName; public List levels; public List enemies; + public int startEnemiesNumber = 1; public Dictionary inventory = new(); public void Awake() { @@ -23,7 +24,7 @@ public class GameController : MonoBehaviour return li; }).ToList(); levels.ForEach(li => { - AddEnemyInLevel(SelectEnemyWeighted().prefab, li.sceneName); + for (int i = 0; i < startEnemiesNumber; ++i) AddEnemyInLevel(SelectEnemyWeighted().prefab, li.sceneName); }); foreach (BulletType i in Enum.GetValues(typeof(BulletType))) { if (i == BulletType.None) continue;