diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 8973a5e..c2f10f2 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -135,6 +135,8 @@ GameObject: - component: {fileID: 519420031} - component: {fileID: 519420029} - component: {fileID: 519420030} + - component: {fileID: 519420033} + - component: {fileID: 519420034} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -249,6 +251,51 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!50 &519420033 +Rigidbody2D: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_BodyType: 0 + m_Simulated: 1 + m_UseFullKinematicContacts: 0 + m_UseAutoMass: 0 + m_Mass: 1 + m_LinearDrag: 0 + m_AngularDrag: 0 + m_GravityScale: 0 + 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: 4 +--- !u!114 &519420034 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 87cffe79f27b53a4593d9cf75ea1d6f9, type: 3} + m_Name: + m_EditorClassIdentifier: + speed: 100 + fastSpeed: 200 + slowSpeed: 30 + maxCameraSize: 100 + minCameraSize: 3 + cameraSizeSteps: 3 --- !u!1 &619394800 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/GridSystem/Grid.cs b/Assets/Scripts/GridSystem/Grid.cs new file mode 100644 index 0000000..b918bca --- /dev/null +++ b/Assets/Scripts/GridSystem/Grid.cs @@ -0,0 +1,95 @@ +using System; +using UnityEngine; + +public class Grid +{ + int width, height; + float cellSize; + Vector3 originPosition; + public TGridObject[,] gridArray; + + bool showDebug = true; + + public int GetWidth() => width; + public int GetHeight() => height; + public float GetCellSize() => cellSize; + + public Grid(int _width, int _height, float _cellSize, Vector3 _originPosition, Func, int, int, TGridObject> createGridObject) + { + width = _width; + height = _height; + cellSize = _cellSize; + originPosition = _originPosition; + + gridArray = new TGridObject[width, height]; + + for (int x = 0; x < gridArray.GetLength(0); x++) + { + for (int y = 0; y < gridArray.GetLength(1); y++) + { + gridArray[x, y] = createGridObject(this, x, y); + } + } + + if (showDebug) + { + for (int x = 0; x < gridArray.GetLength(0); x++) + { + for (int y = 0; y < gridArray.GetLength(1); y++) + { + Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x, y + 1), Color.white, 100f); + Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x + 1, y), Color.white, 100f); + } + } + Debug.DrawLine(GetWorldPosition(0, height), GetWorldPosition(width, height), Color.white, 100f); + Debug.DrawLine(GetWorldPosition(width, 0), GetWorldPosition(width, height), Color.white, 100f); + } + + } + + public Vector3 GetWorldPosition(int x, int y) + { + return new Vector3(x, y) * cellSize + originPosition; + } + + public void GetXY(Vector3 worldPosition, out int x, out int y) + { + x = Mathf.FloorToInt((worldPosition - originPosition).x / cellSize); + y = Mathf.FloorToInt((worldPosition - originPosition).y / cellSize); + } + + public void SetGridObject(int x, int y, TGridObject value) + { + if (x >= 0 && y >= 0 && x < width && y < height) + { + gridArray[x, y] = value; + Debug.Log(x.ToString() + " " + y.ToString() + " -> " + value.ToString()); + } + } + + public void SetGridObject(Vector3 worldPosition, TGridObject value) + { + int x, y; + GetXY(worldPosition, out x, out y); + SetGridObject(x, y, value); + } + + public TGridObject GetGridObject(int x, int y) + { + if (x >= 0 && y >= 0 && x < width && y < height) + { + return gridArray[x, y]; + } + else + { + return default(TGridObject); + } + } + + public TGridObject GetGridObject(Vector3 worldPosition) + { + int x, y; + GetXY(worldPosition, out x, out y); + return GetGridObject(x, y); + } +} \ No newline at end of file diff --git a/Assets/Scripts/GridSystem/Grid.cs.meta b/Assets/Scripts/GridSystem/Grid.cs.meta new file mode 100644 index 0000000..670bd04 --- /dev/null +++ b/Assets/Scripts/GridSystem/Grid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a09de9f61e5400543a4460d8bc195f98 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GridSystem/GridBuildingSystem.cs b/Assets/Scripts/GridSystem/GridBuildingSystem.cs new file mode 100644 index 0000000..575a4c8 --- /dev/null +++ b/Assets/Scripts/GridSystem/GridBuildingSystem.cs @@ -0,0 +1,237 @@ +using System.Collections.Generic; +using UnityEngine; + +// Written with https://www.youtube.com/watch?v=dulosHPl82A +public class GridBuildingSystem : MonoBehaviour +{ + public static GridBuildingSystem instance; + public Grid buildingGrid; + + public int gridWidth; + public int gridHeight; + public float cellSize; + + PlacedObjectTypeSO selectedPlacedObjectTypeSO; + Transform selectedGameObjectTransform; + + public List DEBUG_OBJS = new List(); + + public class GridObject + { + int x, y; + bool isAccessable; // if true, can be placed on -> To limit the building area in the future + Grid grid; + PlacedObject placedObject; + public GridObject(Grid _grid, int _x, int _y, bool _isAccessable = true) // FOR DEBUG TRUE + { + grid = _grid; + x = _x; + y = _y; + isAccessable = _isAccessable; + } + public void SetPlacedObject(PlacedObject newPlacedObject) + { + placedObject = newPlacedObject; + Debug.Log("SetPlacedObject"); + } + public PlacedObject GetPlacedObject() => placedObject; + public void ClearPlacedObject() => placedObject = null; + public void SetIsAccessable(bool _isAccessable) => isAccessable = _isAccessable; + public void SwitchIsAccessable() => isAccessable = !isAccessable; + public bool IsAccessable() => isAccessable; + public bool CanBuild() + { + return placedObject == null && isAccessable; + } + } + void Awake() + { + if (instance == null) + instance = this; + else + Destroy(gameObject); + + buildingGrid = new Grid(gridWidth, gridHeight, cellSize, Vector3.zero, (Grid g, int x, int y) => new GridObject(g, x, y)); + } + + + + void Update() + { + if (selectedGameObjectTransform != null) + { + UpdateSelectedGameObject(); + } + + // DEBUG + if (Input.GetKeyDown(KeyCode.Alpha1)) + { + SelectBuilding(DEBUG_OBJS[0]); + } + + if (Input.GetKeyDown(KeyCode.Alpha2)) + { + SelectBuilding(DEBUG_OBJS[1]); + } + + if (Input.GetKeyDown(KeyCode.Alpha3)) + { + SelectBuilding(DEBUG_OBJS[2]); + } + + if (Input.GetKeyDown(KeyCode.Alpha4)) + { + SelectBuilding(DEBUG_OBJS[3]); + } + + if (Input.GetKeyDown(KeyCode.Alpha5)) + { + SelectBuilding(DEBUG_OBJS[4]); + } + + if (Input.GetKeyDown(KeyCode.Alpha6)) + { + SelectBuilding(DEBUG_OBJS[5]); + } + + if (Input.GetKeyDown(KeyCode.Alpha7)) + { + SelectBuilding(DEBUG_OBJS[6]); + } + + if (Input.GetKeyDown(KeyCode.Alpha8)) + { + SelectBuilding(DEBUG_OBJS[7]); + } + + if (Input.GetKeyDown(KeyCode.Alpha9)) + { + SelectBuilding(DEBUG_OBJS[8]); + } + + } + + + + void UpdateSelectedGameObject() + { + Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); + + buildingGrid.GetXY(mousePosition, out int x, out int y); + + selectedGameObjectTransform.position = buildingGrid.GetWorldPosition(x, y); + + List gridPositionList = selectedPlacedObjectTypeSO.GetGridPositionList(new Vector2Int(x, y)); + + if (CanBuild(gridPositionList)) + { + selectedGameObjectTransform.gameObject.GetComponent().color = Color.white; + } + else + { + selectedGameObjectTransform.gameObject.GetComponent().color = Color.red; + } + + if (Input.GetMouseButtonDown(0)) + { + PlaceBuilding(selectedGameObjectTransform.position); + } + + + if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) + { + DeselectBuilding(); + } + + + } + + public void DemolishBuilding(Vector3 position) + { + GridObject gridObject = buildingGrid.GetGridObject(position); // Camera.main.ScreenToWorldPoint(Input.mousePosition) + PlacedObject placedObject = gridObject.GetPlacedObject(); + + if (placedObject != null) + { + placedObject.DestroySelf(); + + List gridPositionList = placedObject.GetGridPositionList(); + + foreach (Vector2Int gridPosition in gridPositionList) + { + buildingGrid.GetGridObject(gridPosition.x, gridPosition.y).ClearPlacedObject(); + } + } + } + + bool CanBuild(List gridPositionList) + { + bool canBuild = true; + foreach (Vector2Int gridPosition in gridPositionList) + { + if (!buildingGrid.GetGridObject(gridPosition.x, gridPosition.y).CanBuild()) + { + // Cannot build here + canBuild = false; + break; + } + } + return canBuild; + } + + public GameObject PlaceBuilding(Vector3 position) + { + position = new Vector3(position.x, position.y); + buildingGrid.GetXY(position, out int x, out int y); + + List gridPositionList = selectedPlacedObjectTypeSO.GetGridPositionList(new Vector2Int(x, y)); + + // DEBUG + foreach (Vector2Int gridPosition in gridPositionList) + { + Debug.Log(gridPosition); + } + + if (CanBuild(gridPositionList)) + { + PlacedObject placedObject = PlacedObject.Create(buildingGrid.GetWorldPosition(x, y), new Vector2Int(x, y), selectedPlacedObjectTypeSO); + + foreach (Vector2Int gridPosition in gridPositionList) + { + buildingGrid.GetGridObject(gridPosition.x, gridPosition.y).SetPlacedObject(placedObject); + } + return placedObject.gameObject; + } + else + { + Debug.Log("Cannot build here!" + " " + position); + } + return null; + } + + public void SelectBuilding(PlacedObjectTypeSO placedObjectTypeSO) + { + + // Delete all previous blueprints + foreach (GameObject o in GameObject.FindGameObjectsWithTag("PlacedObject")) + { + if (o.GetComponent().GetIsBlueprint()) + { + Destroy(o); + } + } + + Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); + selectedGameObjectTransform = Instantiate(placedObjectTypeSO.prefab, mousePosition, Quaternion.identity); + selectedPlacedObjectTypeSO = placedObjectTypeSO; + } + + public void DeselectBuilding() + { + Destroy(selectedGameObjectTransform.gameObject); + selectedPlacedObjectTypeSO = null; + selectedGameObjectTransform = null; + } + + +} diff --git a/Assets/Scripts/GridSystem/GridBuildingSystem.cs.meta b/Assets/Scripts/GridSystem/GridBuildingSystem.cs.meta new file mode 100644 index 0000000..5569a1d --- /dev/null +++ b/Assets/Scripts/GridSystem/GridBuildingSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1de0d91b0ca828941bdb4c60d0a0f154 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GridSystem/PathfindingSystem.cs b/Assets/Scripts/GridSystem/PathfindingSystem.cs new file mode 100644 index 0000000..50a901d --- /dev/null +++ b/Assets/Scripts/GridSystem/PathfindingSystem.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class PathfindingSystem : MonoBehaviour +{ + public static PathfindingSystem instance { get; private set; } + public Pathfinding pathfinding; + + + + void Start() + { + instance = this; + + int gridWidth = GridBuildingSystem.instance.gridWidth; + int gridHeight = GridBuildingSystem.instance.gridHeight; + float cellSize = GridBuildingSystem.instance.cellSize; + + pathfinding = new Pathfinding(gridWidth, gridHeight, cellSize); + } + + void Update() + { + } +} diff --git a/Assets/Scripts/GridSystem/PathfindingSystem.cs.meta b/Assets/Scripts/GridSystem/PathfindingSystem.cs.meta new file mode 100644 index 0000000..1b31594 --- /dev/null +++ b/Assets/Scripts/GridSystem/PathfindingSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d31ae6efb7031ec4e8b9eeb0ed466657 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GridSystem/PlacedObject.cs b/Assets/Scripts/GridSystem/PlacedObject.cs new file mode 100644 index 0000000..ab4054c --- /dev/null +++ b/Assets/Scripts/GridSystem/PlacedObject.cs @@ -0,0 +1,79 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Tilemaps; + +public abstract class PlacedObject : MonoBehaviour +{ + public static PlacedObject Create(Vector3 worldPosition, Vector2Int origin, PlacedObjectTypeSO placedObjectTypeSO) + { + Transform placeObjectTransform = Instantiate(placedObjectTypeSO.prefab, worldPosition, Quaternion.identity); + + PlacedObject placedObject = placeObjectTransform.GetComponent(); + placedObject.placedObjectTypeSO = placedObjectTypeSO; + placedObject.origin = origin; + + placedObject.OnPlace(); + placedObject.SetIsBlueprint(false); + + if (placedObjectTypeSO.isWalkable) + { + foreach(Vector2Int position in placedObject.GetGridPositionList()) + { + Pathfinding.Instance.GetNode(position.x, position.y).SetIsWalkable(true); + } + + } + + + return placedObject; + } + + public PlacedObjectTypeSO placedObjectTypeSO; + Vector2Int origin; + + [SerializeField] private bool isBlueprint = true; + + public bool GetIsBlueprint() => isBlueprint; + public void SetIsBlueprint(bool newIsBlueprint) + { + + if (GetComponent() != null) + { + if (newIsBlueprint) + { + GetComponent().enabled = false; + } + else + { + GetComponent().enabled = true; + } + } + + isBlueprint = newIsBlueprint; + } + + private void Awake() + { + SetIsBlueprint(true); + } + + public abstract void OnPlace(); + + public List GetGridPositionList() + { + return placedObjectTypeSO.GetGridPositionList(origin); + } + + public void DestroySelf() + { + if (placedObjectTypeSO.isWalkable) + { + foreach (Vector2Int position in GetGridPositionList()) + { + Pathfinding.Instance.GetNode(position.x, position.y).SetIsWalkable(false); + } + } + Destroy(gameObject); + } +} \ No newline at end of file diff --git a/Assets/Scripts/GridSystem/PlacedObject.cs.meta b/Assets/Scripts/GridSystem/PlacedObject.cs.meta new file mode 100644 index 0000000..b2a4926 --- /dev/null +++ b/Assets/Scripts/GridSystem/PlacedObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 024343b97b688a24e8075e525dee8048 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GridSystem/PlacedObjectTypeSO.cs b/Assets/Scripts/GridSystem/PlacedObjectTypeSO.cs new file mode 100644 index 0000000..6ab617d --- /dev/null +++ b/Assets/Scripts/GridSystem/PlacedObjectTypeSO.cs @@ -0,0 +1,31 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +[CreateAssetMenu(menuName = "ScriptableObjects/PlacedObjectTypeSO")] +public class PlacedObjectTypeSO : ScriptableObject +{ + public string placedObjectID; + public string nameString; + public Transform prefab; + public int width; + public int height; + public bool isWalkable = false; + public Sprite iconSprite; + + public List GetGridPositionList(Vector2Int offset) + { + List gridPositionList = new List(); + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + gridPositionList.Add(offset + new Vector2Int(x, y)); + } + } + return gridPositionList; + } + + + +} diff --git a/Assets/Scripts/GridSystem/PlacedObjectTypeSO.cs.meta b/Assets/Scripts/GridSystem/PlacedObjectTypeSO.cs.meta new file mode 100644 index 0000000..ba9b017 --- /dev/null +++ b/Assets/Scripts/GridSystem/PlacedObjectTypeSO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 632704925c0ac0848a70bc1c20e19aba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Pathfinding.meta b/Assets/Scripts/Pathfinding.meta new file mode 100644 index 0000000..56643dc --- /dev/null +++ b/Assets/Scripts/Pathfinding.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4a7b1a013669f324686045e54692cbad +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Pathfinding/PathNode.cs b/Assets/Scripts/Pathfinding/PathNode.cs new file mode 100644 index 0000000..d4f44e0 --- /dev/null +++ b/Assets/Scripts/Pathfinding/PathNode.cs @@ -0,0 +1,39 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class PathNode { + + private Grid grid; + public int x; + public int y; + + public int gCost; + public int hCost; + public int fCost; + + public bool isWalkable; + public PathNode cameFromNode; + + public List neighbourList = new List(); + + public PathNode(Grid _grid, int _x, int _y) { + grid = _grid; + x = _x; + y = _y; + isWalkable = false; + } + + public void CalculateFCost() { + fCost = gCost + hCost; + } + + public void SetIsWalkable(bool isWalkable) { + this.isWalkable = isWalkable; + } + + public override string ToString() { + return x + "," + y; + } + +} diff --git a/Assets/Scripts/Pathfinding/PathNode.cs.meta b/Assets/Scripts/Pathfinding/PathNode.cs.meta new file mode 100644 index 0000000..6be8d36 --- /dev/null +++ b/Assets/Scripts/Pathfinding/PathNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a762ee25504d4344b891ad21350450f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Pathfinding/Pathfinding.cs b/Assets/Scripts/Pathfinding/Pathfinding.cs new file mode 100644 index 0000000..fcfb0aa --- /dev/null +++ b/Assets/Scripts/Pathfinding/Pathfinding.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +public class Pathfinding { + + private const int MOVE_STRAIGHT_COST = 10; + private const int MOVE_DIAGONAL_COST = 14; + + public static Pathfinding Instance { get; private set; } + + private Grid grid; + private List openList; + private List closedList; + + public Pathfinding(int width, int height, float cellSize) { + Instance = this; + grid = new Grid(width, height, cellSize, Vector3.zero, (Grid g, int x, int y) => new PathNode(g, x, y)); + + foreach (PathNode node in grid.gridArray) { + node.neighbourList = GetNeighbourList(node); + } + + } + + public Grid GetGrid() { + return grid; + } + + public List FindPath(Vector3 startWorldPosition, Vector3 endWorldPosition, bool ignoreIsWalkable = false) { + grid.GetXY(startWorldPosition, out int startX, out int startY); + grid.GetXY(endWorldPosition, out int endX, out int endY); + + List path = FindPath(startX, startY, endX, endY, ignoreIsWalkable); + if (path == null) { + return null; + } else { + List vectorPath = new List(); + foreach (PathNode pathNode in path) { + vectorPath.Add(new Vector3(pathNode.x, pathNode.y) * grid.GetCellSize() + Vector3.one * grid.GetCellSize() * .5f); + } + return vectorPath; + } + } + + public List FindPath(int startX, int startY, int endX, int endY, bool ignoreIsWalkable = false) { + var timer = new System.Diagnostics.Stopwatch(); + timer.Start(); + PathNode startNode = grid.GetGridObject(startX, startY); + PathNode endNode = grid.GetGridObject(endX, endY); + + if (startNode == null || endNode == null) { + // Invalid Path + return null; + } + + openList = new List { startNode }; + closedList = new List(); + + for (int x = 0; x < grid.GetWidth(); x++) { + for (int y = 0; y < grid.GetHeight(); y++) { + PathNode pathNode = grid.GetGridObject(x, y); + pathNode.gCost = 99999999; + pathNode.CalculateFCost(); + pathNode.cameFromNode = null; + } + } + + startNode.gCost = 0; + startNode.hCost = CalculateDistanceCost(startNode, endNode); + startNode.CalculateFCost(); + + while (openList.Count > 0) { + PathNode currentNode = GetLowestFCostNode(openList); + if (currentNode == endNode) { + // Reached final node + timer.Stop(); + TimeSpan timeTaken = timer.Elapsed; + Debug.Log("Time taken: " + timeTaken.ToString(@"m\:ss\.fff")); + return CalculatePath(endNode); + } + + openList.Remove(currentNode); + closedList.Add(currentNode); + + foreach (PathNode neighbourNode in currentNode.neighbourList) { + if (closedList.Contains(neighbourNode)) continue; + if (!neighbourNode.isWalkable && !ignoreIsWalkable) { // If neighbouring node is not walkable instantly add them to closed + closedList.Add(neighbourNode); + continue; + } + + int tentativeGCost = currentNode.gCost + CalculateDistanceCost(currentNode, neighbourNode); + if (tentativeGCost < neighbourNode.gCost) { + neighbourNode.cameFromNode = currentNode; + neighbourNode.gCost = tentativeGCost; + neighbourNode.hCost = CalculateDistanceCost(neighbourNode, endNode); + neighbourNode.CalculateFCost(); + + if (!openList.Contains(neighbourNode)) { + openList.Add(neighbourNode); + } + } + } + } + + // Out of nodes on the openList + return null; + } + + private List GetNeighbourList(PathNode currentNode) { + List neighbourList = new List(); + + if (currentNode.x - 1 >= 0) { + // Left + neighbourList.Add(GetNode(currentNode.x - 1, currentNode.y)); + // Left Down + // if (currentNode.y - 1 >= 0) neighbourList.Add(GetNode(currentNode.x - 1, currentNode.y - 1)); + // Left Up + // if (currentNode.y + 1 < grid.GetHeight()) neighbourList.Add(GetNode(currentNode.x - 1, currentNode.y + 1)); + } + if (currentNode.x + 1 < grid.GetWidth()) { + // Right + neighbourList.Add(GetNode(currentNode.x + 1, currentNode.y)); + // Right Down + // if (currentNode.y - 1 >= 0) neighbourList.Add(GetNode(currentNode.x + 1, currentNode.y - 1)); + // Right Up + // if (currentNode.y + 1 < grid.GetHeight()) neighbourList.Add(GetNode(currentNode.x + 1, currentNode.y + 1)); + } + // Down + if (currentNode.y - 1 >= 0) neighbourList.Add(GetNode(currentNode.x, currentNode.y - 1)); + // Up + if (currentNode.y + 1 < grid.GetHeight()) neighbourList.Add(GetNode(currentNode.x, currentNode.y + 1)); + + return neighbourList; + } + + public PathNode GetNode(int x, int y) { + return grid.GetGridObject(x, y); + } + + private List CalculatePath(PathNode endNode) { + List path = new List(); + path.Add(endNode); + PathNode currentNode = endNode; + while (currentNode.cameFromNode != null) { + path.Add(currentNode.cameFromNode); + currentNode = currentNode.cameFromNode; + } + path.Reverse(); + return path; + } + + private int CalculateDistanceCost(PathNode a, PathNode b) { + int xDistance = Mathf.Abs(a.x - b.x); + int yDistance = Mathf.Abs(a.y - b.y); + int remaining = Mathf.Abs(xDistance - yDistance); + return MOVE_DIAGONAL_COST * Mathf.Min(xDistance, yDistance) + MOVE_STRAIGHT_COST * remaining; + } + + private PathNode GetLowestFCostNode(List pathNodeList) { + PathNode lowestFCostNode = pathNodeList[0]; + for (int i = 1; i < pathNodeList.Count; i++) { + if (pathNodeList[i].fCost < lowestFCostNode.fCost) { + lowestFCostNode = pathNodeList[i]; + } + } + return lowestFCostNode; + } + +} diff --git a/Assets/Scripts/Pathfinding/Pathfinding.cs.meta b/Assets/Scripts/Pathfinding/Pathfinding.cs.meta new file mode 100644 index 0000000..6832196 --- /dev/null +++ b/Assets/Scripts/Pathfinding/Pathfinding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5530caa2a712744aa8742d15eb47ac9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Pathfinding/Testing.cs b/Assets/Scripts/Pathfinding/Testing.cs new file mode 100644 index 0000000..bdaecb8 --- /dev/null +++ b/Assets/Scripts/Pathfinding/Testing.cs @@ -0,0 +1,9 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class Testing : MonoBehaviour { + + + +} diff --git a/Assets/Scripts/Pathfinding/Testing.cs.meta b/Assets/Scripts/Pathfinding/Testing.cs.meta new file mode 100644 index 0000000..7af65d6 --- /dev/null +++ b/Assets/Scripts/Pathfinding/Testing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a9e1a4cbcd629e43960027a99f45196 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Player.meta b/Assets/Scripts/Player.meta new file mode 100644 index 0000000..eb7ec7f --- /dev/null +++ b/Assets/Scripts/Player.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 97b8c1d7083d3f64db4eb6b3bed60c52 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Player/CameraMovement.cs b/Assets/Scripts/Player/CameraMovement.cs new file mode 100644 index 0000000..3a8b3f6 --- /dev/null +++ b/Assets/Scripts/Player/CameraMovement.cs @@ -0,0 +1,102 @@ +using UnityEngine; + +public class CameraMovement : MonoBehaviour +{ + [Header("Speed")] + [SerializeField] + float speed = 150f; + + [SerializeField] + float fastSpeed = 300f; + + [SerializeField] + float slowSpeed = 50f; + + [Header("Zoom")] + [SerializeField] + float maxCameraSize = 100f; + + [SerializeField] + float minCameraSize = 3f; + + [SerializeField] + float cameraSizeSteps = 3f; + + Vector2 cameraMovement; + float currentSpeed = 0.0f; + + bool drag = false; + + Vector3 origin; + Vector3 difference; + + + + Camera cam; + Rigidbody2D rb; + + void Start() + { + cam = GetComponent(); + rb = GetComponent(); + } + + void LateUpdate() + { + if (Input.GetMouseButton(2)) + { + difference = (cam.ScreenToWorldPoint(Input.mousePosition) - cam.transform.position); + if (!drag) + { + drag = true; + origin = cam.ScreenToWorldPoint(Input.mousePosition); + } + } + else + { + drag = false; + } + + if (drag) + { + cam.transform.position = origin - difference; + } + } + + void Update() + { + currentSpeed = speed; + + cameraMovement.x = Input.GetAxis("Horizontal"); + cameraMovement.y = Input.GetAxis("Vertical"); + + if (Input.GetButton("CameraFast")) + currentSpeed = fastSpeed; + else if (Input.GetButton("CameraSlow")) + currentSpeed = slowSpeed; + + + if (Input.GetAxis("Mouse ScrollWheel") > 0f) + ZoomCameraToPoint(cam.ScreenToWorldPoint(Input.mousePosition), cameraSizeSteps); + else if (Input.GetAxis("Mouse ScrollWheel") < 0f) + ZoomCameraToPoint(cam.ScreenToWorldPoint(Input.mousePosition), -cameraSizeSteps); + + + } + + void FixedUpdate() + { + rb.MovePosition(rb.position + cameraMovement * currentSpeed * Time.fixedDeltaTime); + } + + void ZoomCameraToPoint(Vector3 point, float amount) + { + float multiplier = (1.0f / cam.orthographicSize * amount); + + transform.position += (point - transform.position) * multiplier; + + cam.orthographicSize -= amount; + + cam.orthographicSize = Mathf.Clamp(cam.orthographicSize, minCameraSize, maxCameraSize); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Player/CameraMovement.cs.meta b/Assets/Scripts/Player/CameraMovement.cs.meta new file mode 100644 index 0000000..37bb70b --- /dev/null +++ b/Assets/Scripts/Player/CameraMovement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87cffe79f27b53a4593d9cf75ea1d6f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset index b16147e..542bd1b 100644 --- a/ProjectSettings/InputManager.asset +++ b/ProjectSettings/InputManager.asset @@ -485,3 +485,36 @@ InputManager: type: 2 axis: 5 joyNum: 0 + - serializedVersion: 3 + m_Name: CameraFast + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: CameraSlow + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + m_UsePhysicalKeys: 1