From fd8778e9f28cc1a03858c6983c449382a9fdeb98 Mon Sep 17 00:00:00 2001 From: reisenlol Date: Sun, 4 Jan 2026 22:28:34 -0800 Subject: [PATCH] basic enemy movement --- Assets/Scenes/Prototype.unity | 234 ++++++++++++++++++++++++- Assets/Scripts/Enemy.cs | 3 + Assets/Scripts/EnemyMovement.cs | 104 +++++++++++ Assets/Scripts/EnemyMovement.cs.meta | 2 + Assets/Scripts/PlayerEntityMovement.cs | 42 ++++- Assets/Scripts/TurnHandler.cs | 7 +- 6 files changed, 377 insertions(+), 15 deletions(-) create mode 100644 Assets/Scripts/EnemyMovement.cs create mode 100644 Assets/Scripts/EnemyMovement.cs.meta diff --git a/Assets/Scenes/Prototype.unity b/Assets/Scenes/Prototype.unity index 3a705db..6ec9296 100644 --- a/Assets/Scenes/Prototype.unity +++ b/Assets/Scenes/Prototype.unity @@ -479,7 +479,7 @@ MonoBehaviour: m_EditorClassIdentifier: health: 100 maxHealth: 100 - maxMovement: 3 + maxMovement: 10 currentTile: {fileID: 0} canMove: 1 invincible: 0 @@ -655,6 +655,189 @@ MonoBehaviour: m_PostInfinity: 2 m_RotationOrder: 4 CustomBlends: {fileID: 0} +--- !u!1 &589901455 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 589901460} + - component: {fileID: 589901459} + - component: {fileID: 589901458} + - component: {fileID: 589901457} + - component: {fileID: 589901456} + m_Layer: 0 + m_Name: Enemy + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &589901456 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589901455} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 441b69580fe55f47ead9c7266bb4d363, type: 3} + m_Name: + m_EditorClassIdentifier: + health: 100 + maxHealth: 100 + maxMovement: 4 + currentTile: {fileID: 0} + canMove: 1 + invincible: 0 + turnSpeed: 1 + minimumAttackRange: 10 +--- !u!50 &589901457 +Rigidbody2D: + serializedVersion: 5 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589901455} + m_BodyType: 2 + m_Simulated: 1 + m_UseFullKinematicContacts: 0 + m_UseAutoMass: 0 + m_Mass: 1 + m_LinearDamping: 0 + m_AngularDamping: 0.05 + m_GravityScale: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_Interpolate: 0 + m_SleepingMode: 1 + m_CollisionDetection: 0 + m_Constraints: 0 +--- !u!61 &589901458 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589901455} + m_Enabled: 1 + serializedVersion: 3 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_CompositeOperation: 0 + m_CompositeOrder: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1} + newSize: {x: 1, y: 1} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + m_Size: {x: 1, y: 1} + m_EdgeRadius: 0 +--- !u!212 &589901459 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589901455} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 7482667652216324306, guid: 311925a002f4447b3a28927169b83ea6, type: 3} + m_Color: {r: 1, g: 0, b: 0, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!4 &589901460 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 589901455} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -2.5, y: 1.5, z: 0} + m_LocalScale: {x: 0.8, y: 0.8, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &619394800 GameObject: m_ObjectHideFlags: 0 @@ -739,6 +922,50 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &925678149 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 925678151} + - component: {fileID: 925678150} + m_Layer: 0 + m_Name: EnemyMovement + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &925678150 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 925678149} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5480895c85041d2e492c0ccbfa17254a, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &925678151 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 925678149} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1049538432 GameObject: m_ObjectHideFlags: 0 @@ -772,7 +999,8 @@ MonoBehaviour: - {fileID: 287802167} - {fileID: 1716557180} - {fileID: 1710585246} - enemyEntities: [] + enemyEntities: + - {fileID: 589901456} currentGameState: 0 --- !u!4 &1049538434 Transform: @@ -1293,3 +1521,5 @@ SceneRoots: - {fileID: 1389484819} - {fileID: 1049538434} - {fileID: 1764165478} + - {fileID: 589901460} + - {fileID: 925678151} diff --git a/Assets/Scripts/Enemy.cs b/Assets/Scripts/Enemy.cs index aed5298..a9f6b5e 100644 --- a/Assets/Scripts/Enemy.cs +++ b/Assets/Scripts/Enemy.cs @@ -11,11 +11,14 @@ public class Enemy : Entity turnSpeed = Random.Range(0, 100); } + [ContextMenu("ForceTurn")] public void StartTurn() { //attack the nearest player? TurnHandler.instance.UpdateTurns(); closestPlayer = FindClosestPlayer(); + Debug.Log(closestPlayer); + EnemyMovement.instance.PathfindToTarget(closestPlayer.currentTile.neighbors[Random.Range(0, closestPlayer.currentTile.neighbors.Count)], this); } private PlayerEntity FindClosestPlayer() diff --git a/Assets/Scripts/EnemyMovement.cs b/Assets/Scripts/EnemyMovement.cs new file mode 100644 index 0000000..f9420b8 --- /dev/null +++ b/Assets/Scripts/EnemyMovement.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using UnityEngine; + +public class EnemyMovement : MonoBehaviour +{ + #region Statication + + public static EnemyMovement instance; + + private void Awake() + { + if (instance != null && instance != this) + { + Destroy(gameObject); + return; + } + instance = this; + } + + #endregion + private Queue allMovableTiles = new(); + private Queue currentMovableTiles = new(); + private Dictionary currentPaths = new(); + + public void PathfindToTarget(TileObject target, Enemy selectedEntity) + { + allMovableTiles.Clear(); + currentMovableTiles.Clear(); + currentPaths.Clear(); + GetTilesInRange(selectedEntity); + TileObject requestedTile = GetPathToTarget(target, selectedEntity); + selectedEntity.currentTile = requestedTile; + selectedEntity.transform.position = requestedTile.transform.position; + } + private void GetTilesInRange(Enemy selectedEntity) + { + foreach (TileObject tileObject in selectedEntity.currentTile.neighbors) + { + if (!tileObject.blocked && !tileObject.hasUnit) + { + currentMovableTiles.Enqueue(tileObject); + allMovableTiles.Enqueue(tileObject); + currentPaths.Add(tileObject, selectedEntity.currentTile); + } + } + for (int i = 0; i < selectedEntity.maxMovement - 1; i++) + { + foreach (TileObject tileObject in currentMovableTiles.ToArray()) + { + foreach (TileObject neighboringTiles in tileObject.neighbors) + { + if (!neighboringTiles.blocked && !neighboringTiles.hasUnit) + { + currentMovableTiles.Enqueue(neighboringTiles); + currentPaths.TryAdd(neighboringTiles, tileObject); + } + } + } + } + foreach (TileObject tileObject in allMovableTiles.ToArray()) + { + foreach (TileObject neighboringTiles in tileObject.neighbors) + { + if (!neighboringTiles.blocked && !neighboringTiles.hasUnit) + { + allMovableTiles.Enqueue(neighboringTiles); + currentPaths.TryAdd(neighboringTiles, tileObject); + } + } + } + } + + private TileObject GetPathToTarget(TileObject target, Enemy selectedEntity) + { + TileObject currentTile = target; + List pathToTarget = new(); + TileObject pathTileInRange = null; + while (currentTile != selectedEntity.currentTile) + { + pathToTarget.Add(currentTile); + currentTile = currentPaths[currentTile]; + } + + for (int i = 0; i < pathToTarget.Count; i++) + { + if (currentMovableTiles.Contains(pathToTarget[i])) + { + pathTileInRange = pathToTarget[i]; + return pathTileInRange; + } + } + List pathToRange = new(); + /*if (pathTileInRange != null) + { + while (pathTileInRange != selectedEntity.currentTile) + { + pathToTarget.Add(pathTileInRange); + pathTileInRange = currentPaths[pathTileInRange]; + } + return pathToRange; + }*/ + return null; + } +} diff --git a/Assets/Scripts/EnemyMovement.cs.meta b/Assets/Scripts/EnemyMovement.cs.meta new file mode 100644 index 0000000..2569780 --- /dev/null +++ b/Assets/Scripts/EnemyMovement.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5480895c85041d2e492c0ccbfa17254a \ No newline at end of file diff --git a/Assets/Scripts/PlayerEntityMovement.cs b/Assets/Scripts/PlayerEntityMovement.cs index 431c97c..3ebf19c 100644 --- a/Assets/Scripts/PlayerEntityMovement.cs +++ b/Assets/Scripts/PlayerEntityMovement.cs @@ -35,7 +35,10 @@ public class PlayerEntityMovement : MonoBehaviour public LayerMask playerLayer; - private List currentMovableTiles = new(); + private Queue currentMovableTiles = new(); + private Dictionary paths = new(); + private List currentPath = new(); + private TileObject requestedTile; private void Start() { @@ -52,6 +55,29 @@ public class PlayerEntityMovement : MonoBehaviour } if (isMoving) { + TileObject newTile = GridManager.instance.GetTile(mouseGridPos); + if (requestedTile != newTile) + { + requestedTile = newTile; + foreach (TileObject tile in currentPath) + { + tile.sprite.color = Color.green; + } + currentPath.Clear(); + if (currentMovableTiles.Contains(requestedTile)) + { + TileObject currentTile = requestedTile; + while (currentTile != selectedEntity.currentTile) + { + currentPath.Add(currentTile); + currentTile = paths[currentTile]; + } + foreach (TileObject tile in currentPath) + { + tile.sprite.color = Color.blue; + } + } + } templateObject.transform.position = mouseGridPos; if (Input.GetMouseButtonDown(0) && debounceTime <= 0 && SelectLocation()) { @@ -67,11 +93,13 @@ public class PlayerEntityMovement : MonoBehaviour debounceTime = debounceDuration; //alotta for loops here UncolorGrid(); currentMovableTiles.Clear(); + paths.Clear(); foreach (TileObject tileObject in selectedEntity.currentTile.neighbors) { if (!tileObject.blocked && !tileObject.hasUnit) { - currentMovableTiles.Add(tileObject); + currentMovableTiles.Enqueue(tileObject); + paths.Add(tileObject, selectedEntity.currentTile); tileObject.sprite.color = Color.green; } } @@ -83,8 +111,9 @@ public class PlayerEntityMovement : MonoBehaviour { if (!neighboringTiles.blocked && !neighboringTiles.hasUnit) { - currentMovableTiles.Add(neighboringTiles); + currentMovableTiles.Enqueue(neighboringTiles); neighboringTiles.sprite.color = Color.green; + paths.TryAdd(neighboringTiles, tileObject); } } } @@ -102,14 +131,13 @@ public class PlayerEntityMovement : MonoBehaviour private bool SelectLocation() { - TileObject selectedTile = GridManager.instance.GetTile(mouseGridPos); - if (!selectedTile || selectedTile.blocked || selectedTile.hasUnit || !currentMovableTiles.Contains(selectedTile)) + if (!requestedTile || requestedTile.blocked || requestedTile.hasUnit || !currentMovableTiles.Contains(requestedTile)) { return false; } selectedEntity.currentTile.hasUnit = false; - selectedTile.hasUnit = true; - selectedEntity.currentTile = selectedTile; + requestedTile.hasUnit = true; + selectedEntity.currentTile = requestedTile; selectedEntity.transform.position = mouseGridPos; templateObject.SetActive(false); UncolorGrid(); diff --git a/Assets/Scripts/TurnHandler.cs b/Assets/Scripts/TurnHandler.cs index accc708..27a0ef2 100644 --- a/Assets/Scripts/TurnHandler.cs +++ b/Assets/Scripts/TurnHandler.cs @@ -52,12 +52,7 @@ public class TurnHandler : MonoBehaviour } if (allDone) { - foreach (PlayerEntity player in playerEntities) - { - player.hasMoved = false; - player.hasAttacked = false; - } - //currentGameState = GameState.EnemyTurn; + currentGameState = GameState.EnemyTurn; } } else if (currentGameState == GameState.EnemyTurn)