Added pathfinding and basics of bot movement

This commit is contained in:
AlexMamontow 2021-08-07 17:23:31 +03:00
parent 8483d0ef43
commit 3210fc245e
17 changed files with 3935 additions and 382 deletions

70
Assets/AI_Input.cs Normal file
View File

@ -0,0 +1,70 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class AI_Input : MonoBehaviour
{
public Vector2 leftInput, rightInput;
public Action OnTouchDown, OnTouchUp;
public List<TileInfo> _currentFollowingPath;
public List<TileInfo> _testPath;
private PlayerState _playerState;
private TileMovement _tileMovement;
private const int endIndex = 160;
private void Awake()
{
_playerState = GetComponent<PlayerState>();
_tileMovement = GetComponent<TileMovement>();
//_playerState.OnCharStateChanged += RecalculatePath;
_tileMovement.OnStartMovement += RecalculatePath;
_playerState.OnInitializied += StartBehaviour;
}
private void StartBehaviour()
{
var endTile = TileManagment.levelTiles[endIndex];
var startTile = _playerState.currentTile;
_currentFollowingPath = Pathfinding.FindPath(startTile, endTile, TileManagment.tileOffset);
_testPath = _currentFollowingPath;
}
private void Start()
{
}
private void RecalculatePath(ActionType newType, CharacterState newState)
{
/*if (_currentFollowingPath.Count <= 0)
return;*/
/*if (_testPath.Count > 0)
{
var endTile = _testPath[_testPath.Count - 1];
var currentTile = _testPath[1];
//_currentFollowingPath.Clear();
_testPath = Pathfinding.FindPath(currentTile, endTile, TileManagment.tileOffset);
Debug.Log("recalculated, currentTile is " + currentTile.name);
}*/
}
private void Update()
{
var cuurentTile = _playerState.currentTile;
int nextTileIndex = _currentFollowingPath.IndexOf(cuurentTile)+1;
if (nextTileIndex <= _currentFollowingPath.Count - 1)
{
leftInput = TileManagment.GetJoystickDirection(cuurentTile, _currentFollowingPath[nextTileIndex]);
}
else
{
leftInput = Vector2.zero;
}
}
}

11
Assets/AI_Input.cs.meta Normal file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 910a443bbcb74e44cb5ccf12a169accb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -6,14 +6,14 @@ using UnityEngine;
[RequireComponent(typeof(PlayerState))] [RequireComponent(typeof(PlayerState))]
public class AnimationController : MonoBehaviour public class AnimationController : MonoBehaviour
{ {
public Animator characterAnimator; private Animator _characterAnimator;
private PlayerState _playerState; private PlayerState _playerState;
private void Start() private void Start()
{ {
_playerState = GetComponent<PlayerState>(); _playerState = GetComponent<PlayerState>();
_characterAnimator = GetComponentInChildren<Animator>();
_playerState.OnCharStateChanged += SetNewStateAnimation; _playerState.OnCharStateChanged += SetNewStateAnimation;
} }
@ -36,7 +36,7 @@ public class AnimationController : MonoBehaviour
} }
if (activationTrigger != "") if (activationTrigger != "")
{ {
characterAnimator.SetTrigger(activationTrigger); _characterAnimator.SetTrigger(activationTrigger);
} }
} }

View File

@ -11,7 +11,7 @@ public class CaptureController : MonoBehaviour
private TileOwner _ownerIndex; private TileOwner _ownerIndex;
private TileManagment _tileManagment; private TileManagment _tileManagment;
private PlayerState _playerState; public PlayerState _playerState;
private float _captureProgress= 0f; private float _captureProgress= 0f;
@ -20,7 +20,7 @@ public class CaptureController : MonoBehaviour
private IEnumerator _currentCoroutine; private IEnumerator _currentCoroutine;
private void Start() private void Awake()
{ {
_playerState = GetComponent<PlayerState>(); _playerState = GetComponent<PlayerState>();
_tileManagment = FindObjectOfType<TileManagment>(); _tileManagment = FindObjectOfType<TileManagment>();
@ -32,10 +32,13 @@ public class CaptureController : MonoBehaviour
OnCaptureEnd += CaptureTile; OnCaptureEnd += CaptureTile;
} }
private void CaptureStartTile() private void CaptureStartTile()
{ {
//Debug.Log("start tile cap");
_ownerIndex = _playerState.ownerIndex; _ownerIndex = _playerState.ownerIndex;
_tileManagment.ChangeTileOwner(_playerState.currentTile, _ownerIndex); _tileManagment.ChangeTileOwner(_playerState.currentTile, _ownerIndex);
} }
private void StopCapturingTile() private void StopCapturingTile()

View File

@ -2,12 +2,10 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using System;
public class CustomInput : MonoBehaviour public class CustomInput : MonoBehaviour
{ {
public static Vector2 leftInput, rightInput; public static Vector2 leftInput, rightInput;
public static float rightRegistrationDeadZone = 0.3f;
public static Action OnTouchDown, OnTouchUp; public static Action OnTouchDown, OnTouchUp;

View File

@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PathNode : MonoBehaviour
{
//public Vector2 position = Vector3.zero;
public float gCost = 0f;
public float hCost = 0f;
public float fCost = 0f;
public PathNode parent = null;
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f2ee77e00b118ba4bb59a8cd07d7a399
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,104 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pathfinding : MonoBehaviour
{
public static List<TileInfo> FindPath(TileInfo startTile, TileInfo endTile, float tileOffset)
{
var openNodes = new List<PathNode>();
var closedNodes = new List<PathNode>();
var startNode = startTile.GetComponent<PathNode>();
var endNode = endTile.GetComponent<PathNode>();
startNode.gCost = 0f;
startNode.hCost = Vector3.Distance(startNode.transform.position, endNode.transform.position);
startNode.fCost = startNode.gCost + startNode.hCost;
openNodes.Add(startNode);
while (openNodes.Count > 0)
{
var currentNode = openNodes[0]; //looking for lowest value node
foreach (var node in openNodes)
{
if (node.fCost < currentNode.fCost)
{
currentNode = node;
}
}
if (currentNode == endNode)
{
return GetPathForNode(currentNode);
}
openNodes.Remove(currentNode);
closedNodes.Add(currentNode);
Debug.Log(currentNode.name);
foreach (PathNode newNode in GetAdjacentNodes(currentNode))
{
if (newNode)
{
if (closedNodes.Contains(newNode))
{
continue;
}
if (!openNodes.Contains(newNode))
{
SetNodeParams(newNode, currentNode, endNode, tileOffset);
openNodes.Add(newNode);
}
else
{
if (currentNode.gCost + tileOffset < newNode.gCost)
{
newNode.gCost = currentNode.gCost + tileOffset;
newNode.parent = currentNode;
newNode.fCost = newNode.gCost + newNode.hCost;
}
}
}
}
}
Debug.Log("path not found");
return null;
}
private static List<PathNode> GetAdjacentNodes(PathNode currentNode)
{
var allAjacentTiles = TileManagment.GetAllTiles(currentNode.GetComponent<TileInfo>());
List<PathNode> adjacentNodes = new List<PathNode>();
foreach (TileInfo tile in allAjacentTiles)
{
if (tile.canMove)
{
adjacentNodes.Add(tile.GetComponent<PathNode>());
}
}
return adjacentNodes;
}
private static List<TileInfo> GetPathForNode(PathNode pathNode)
{
var result = new List<TileInfo>();
var currentNode = pathNode;
while (currentNode != null)
{
result.Add(currentNode.GetComponent<TileInfo>());
currentNode = currentNode.parent;
}
result.Reverse();
Debug.Log("path found");
return result;
}
private static void SetNodeParams(PathNode currentNode, PathNode parrentNode, PathNode endNode, float nodeOffset)
{
currentNode.parent = parrentNode;
currentNode.gCost = currentNode.parent.gCost + nodeOffset;
currentNode.hCost = Vector3.Distance(currentNode.transform.position, endNode.transform.position);
currentNode.fCost = currentNode.gCost + currentNode.hCost;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71415f1be86de7d4e9790a2f92faa1e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -16,15 +16,13 @@ public class PlayerActionManager : MonoBehaviour
private PlayerState _playerState; private PlayerState _playerState;
private PlayerAction _currentAction; private PlayerAction _currentAction;
private IEnumerator _currentCoroutine;
private TileInfo _target; private TileInfo _target;
private float _actionProgress; private float _actionProgress;
private void Awake() private void Awake()
{ {
_playerState = FindObjectOfType<PlayerState>(); _playerState = GetComponent<PlayerState>();
_playerState.OnActionChanged += SetNewCurrentAction; _playerState.OnActionChanged += SetNewCurrentAction;
CustomInput.OnTouchDown += StartTargeting; CustomInput.OnTouchDown += StartTargeting;
@ -87,7 +85,6 @@ public class PlayerActionManager : MonoBehaviour
OnLostTarget?.Invoke(); OnLostTarget?.Invoke();
//StopCoroutine(_currentCoroutine); //StopCoroutine(_currentCoroutine);
StopAllCoroutines(); StopAllCoroutines();
_currentCoroutine = null;
_target = null; _target = null;
} }

View File

@ -10,6 +10,7 @@ public class PlayerState : MonoBehaviour
public CharacterState currentState; public CharacterState currentState;
public TileOwner ownerIndex = TileOwner.Ariost; public TileOwner ownerIndex = TileOwner.Ariost;
public ActionType currentAction = ActionType.Attack; public ActionType currentAction = ActionType.Attack;
public ControlType controlType = ControlType.Player;
public TileInfo currentTile; public TileInfo currentTile;
@ -94,7 +95,7 @@ public class PlayerState : MonoBehaviour
public bool IsAnyActionsAllowed() public bool IsAnyActionsAllowed()
{ {
return currentTile.tileOwnerIndex == ownerIndex && currentState == CharacterState.Idle; return (currentTile.tileOwnerIndex == ownerIndex) && (currentState == CharacterState.Idle);
} }
} }
@ -119,3 +120,9 @@ public enum ActionType
Attack, Attack,
Build, Build,
} }
public enum ControlType
{
Player,
AI
}

View File

@ -17,7 +17,7 @@ public class TileInfo : MonoBehaviour
public bool isBorderTile = false; public bool isBorderTile = false;
public bool isChecked = false; //public bool isChecked = false;
} }

View File

@ -8,9 +8,11 @@ public class TileManagment : MonoBehaviour
public const int BASIC_DIRECTIONS = 6; public const int BASIC_DIRECTIONS = 6;
public static List<TileInfo> levelTiles = new List<TileInfo>(); public static List<TileInfo> levelTiles = new List<TileInfo>();
public static List<TileInfo> ariostTiles = new List<TileInfo>();
public static List<List<TileInfo>> charTiles = new List<List<TileInfo>>();
public List<Material> tileMaterials; public List<Material> tileMaterials;
//public List<TileInfo> pathTiles = new List<TileInfo>();
public static float tileOffset; public static float tileOffset;
@ -18,6 +20,7 @@ public class TileManagment : MonoBehaviour
private void Awake() private void Awake()
{ {
InitCharTiles();
for (int i = 0; i < transform.childCount; i++) for (int i = 0; i < transform.childCount; i++)
{ {
var tile = transform.GetChild(i).GetComponent<TileInfo>(); var tile = transform.GetChild(i).GetComponent<TileInfo>();
@ -25,10 +28,7 @@ public class TileManagment : MonoBehaviour
{ {
levelTiles.Add(tile); levelTiles.Add(tile);
SetTileStartParams(tile); SetTileStartParams(tile);
if (tile.tileOwnerIndex == TileOwner.Ariost) charTiles[(int)tile.tileOwnerIndex].Add(tile);
{
ariostTiles.Add(tile);
}
} }
} }
@ -38,11 +38,21 @@ public class TileManagment : MonoBehaviour
} }
private void InitCharTiles()
{
for (int i = 0; i < tileMaterials.Count; i++)
{
List<TileInfo> charTileList = new List<TileInfo>();
charTiles.Add(charTileList); //init empty lists for character tiles
}
}
private void Start() private void Start()
{ {
//Debug.Log("We have "+ levelTiles.Count + " tiles on this level"); //Debug.Log("We have "+ levelTiles.Count + " tiles on this level");
//Debug.Log("Tiles offset "+ _tilesOffset +" units"); //Debug.Log("Tiles offset "+ _tilesOffset +" units");
//Debug.Log(GetTile(new Vector3(0f, 0f, 0f), new Vector3(-0.9f, 0f, 1.7f), 1)); //Debug.Log(GetTile(new Vector3(0f, 0f, 0f), new Vector3(-0.9f, 0f, 1.7f), 1));
//pathTiles = Pathfinding.FindPath(levelTiles[0].GetComponent<PathNode>(), levelTiles[106].GetComponent<PathNode>(), tileOffset);
if (tileMaterials.Count == 0) if (tileMaterials.Count == 0)
{ {
Debug.LogError("You need to set tile materials to TileManagment"); Debug.LogError("You need to set tile materials to TileManagment");
@ -62,10 +72,10 @@ public class TileManagment : MonoBehaviour
tile.tileOwnerIndex = ownerIndex; tile.tileOwnerIndex = ownerIndex;
tile.GetComponent<Renderer>().material = tileMaterials[(int)tile.tileOwnerIndex]; tile.GetComponent<Renderer>().material = tileMaterials[(int)tile.tileOwnerIndex];
ariostTiles.Add(tile); charTiles[(int)ownerIndex].Add(tile);
//Debug.Log(GetOtherTiles(tile).Count); //Debug.Log(GetOtherTiles(tile).Count);
CheckSurroundedTiles(levelTiles, ownerIndex, tile); //CheckSurroundedTiles(levelTiles, ownerIndex, tile);
//Debug.Log("Captured " + tile.name); //Debug.Log("Captured " + tile.name);
} }
@ -110,7 +120,7 @@ public class TileManagment : MonoBehaviour
//int notMyTiles = 0; //int notMyTiles = 0;
foreach (Vector3 dir in basicDirections) foreach (Vector3 dir in basicDirections)
{ {
var tile = GetTile(currentTile.tilePosition + dir * TileManagment.tileOffset); var tile = GetTile(currentTile.tilePosition + dir * tileOffset);
if (tile) if (tile)
{ {
if (tile.tileOwnerIndex != ownerIndex) if (tile.tileOwnerIndex != ownerIndex)
@ -124,6 +134,31 @@ public class TileManagment : MonoBehaviour
return otherTiles; return otherTiles;
} }
public static Vector2 GetJoystickDirection(TileInfo currentTile, TileInfo adjacentTile)
{
if (!currentTile || !adjacentTile)
return Vector2.zero;
Vector3 dir3 = adjacentTile.tilePosition - currentTile.tilePosition;
Vector2 dir2 = new Vector2(dir3.x, dir3.z);
return dir2;
}
public static List<TileInfo> GetAllTiles(TileInfo currentTile)
{
List<TileInfo> allTiles = new List<TileInfo>();
//int notMyTiles = 0;
foreach (Vector3 dir in basicDirections)
{
var tile = GetTile(currentTile.tilePosition + dir * tileOffset);
if (tile)
{
allTiles.Add(tile);
}
}
//Debug.Log("We have " + notMyTiles + " not my tiles around " + currentTile.name);
return allTiles;
}
public static Vector3[] GetBasicDirections(int directionsAmount) public static Vector3[] GetBasicDirections(int directionsAmount)
{ {
Vector3[] tempArr = new Vector3[directionsAmount]; Vector3[] tempArr = new Vector3[directionsAmount];
@ -138,10 +173,10 @@ public class TileManagment : MonoBehaviour
public static void CheckSurroundedTiles(List<TileInfo> tiles, TileOwner ownerIndex, TileInfo startTile) public static void CheckSurroundedTiles(List<TileInfo> tiles, TileOwner ownerIndex, TileInfo startTile)
{ {
foreach (TileInfo tile in tiles) /*foreach (TileInfo tile in tiles)
{ {
tile.isChecked = false; tile.isChecked = false;
} }*/
List<TileInfo> firstAdjacentTiles = GetOtherTiles(startTile, ownerIndex); List<TileInfo> firstAdjacentTiles = GetOtherTiles(startTile, ownerIndex);
foreach (TileInfo tile in firstAdjacentTiles) foreach (TileInfo tile in firstAdjacentTiles)
{ {
@ -178,7 +213,7 @@ public class TileManagment : MonoBehaviour
} }
surroundedTiles.Add(tile); surroundedTiles.Add(tile);
tile.isChecked = true; //tile.isChecked = true;
var adjacentTiles = GetOtherTiles(tile, ownerIndex); var adjacentTiles = GetOtherTiles(tile, ownerIndex);
//Debug.Log("second tiles "+ adjacentTiles.Count); //Debug.Log("second tiles "+ adjacentTiles.Count);

View File

@ -5,7 +5,6 @@ using UnityEngine;
using DG.Tweening; using DG.Tweening;
[RequireComponent(typeof(PlayerState))] [RequireComponent(typeof(PlayerState))]
[RequireComponent(typeof(CaptureController))]
public class TileMovement : MonoBehaviour public class TileMovement : MonoBehaviour
{ {
@ -17,10 +16,12 @@ public class TileMovement : MonoBehaviour
public Action<ActionType, CharacterState> OnStartMovement; public Action<ActionType, CharacterState> OnStartMovement;
private PlayerState _playerState; private PlayerState _playerState;
private AI_Input _AIInput;
private void Start() private void Start()
{ {
_playerState = GetComponent<PlayerState>(); _playerState = GetComponent<PlayerState>();
_AIInput = GetComponent<AI_Input>();
} }
private void Update() private void Update()
@ -32,12 +33,24 @@ public class TileMovement : MonoBehaviour
{ {
if (_playerState.currentState != CharacterState.Idle) if (_playerState.currentState != CharacterState.Idle)
return; return;
switch (_playerState.controlType)
{
case ControlType.Player:
_moveDir = new Vector3(CustomInput.leftInput.x, 0f, CustomInput.leftInput.y); _moveDir = new Vector3(CustomInput.leftInput.x, 0f, CustomInput.leftInput.y);
break;
case ControlType.AI:
_moveDir = new Vector3(_AIInput.leftInput.x, 0f, _AIInput.leftInput.y);
break;
}
//_moveDir = new Vector3(CustomInput.leftInput.x, 0f, CustomInput.leftInput.y);
if (_moveDir.magnitude > Mathf.Epsilon) if (_moveDir.magnitude > Mathf.Epsilon)
{ {
TileInfo targetMoveTile = TileManagment.GetTile(_playerState.currentTile.tilePosition, _moveDir, 1); TileInfo targetMoveTile = TileManagment.GetTile(_playerState.currentTile.tilePosition, _moveDir, moveDistance);
//Debug.Log("moving to " + targetMoveTile);
if (IsMovementAllowed(targetMoveTile)) if (IsMovementAllowed(targetMoveTile))
{ {
//Debug.Log(IsMovementAllowed(targetMoveTile));
MoveToTile(targetMoveTile); MoveToTile(targetMoveTile);
} }
} }
@ -51,10 +64,12 @@ public class TileMovement : MonoBehaviour
bool canMoveToMyTile = (tile.tileOwnerIndex == _playerState.ownerIndex); bool canMoveToMyTile = (tile.tileOwnerIndex == _playerState.ownerIndex);
bool canMoveToEnemyTile = (_playerState.currentTile.tileOwnerIndex == _playerState.ownerIndex); bool canMoveToEnemyTile = (_playerState.currentTile.tileOwnerIndex == _playerState.ownerIndex);
return tile.canMove && (canMoveToMyTile || canMoveToEnemyTile); return tile.canMove && (canMoveToMyTile || canMoveToEnemyTile);
} }
else else
{ {
//Debug.Log("moving " + gameObject.name);
return false; return false;
} }
@ -63,6 +78,7 @@ public class TileMovement : MonoBehaviour
private void MoveToTile(TileInfo targetMoveTile) private void MoveToTile(TileInfo targetMoveTile)
{ {
OnStartMovement?.Invoke(ActionType.Attack, CharacterState.Move); OnStartMovement?.Invoke(ActionType.Attack, CharacterState.Move);
_playerState.currentTile.canMove = true;
transform.DOMove(targetMoveTile.tilePosition, nextTileMoveTime).OnComplete(()=> FinishMovementActions(targetMoveTile)); transform.DOMove(targetMoveTile.tilePosition, nextTileMoveTime).OnComplete(()=> FinishMovementActions(targetMoveTile));
transform.LookAt(targetMoveTile.tilePosition); transform.LookAt(targetMoveTile.tilePosition);
} }
@ -71,6 +87,7 @@ public class TileMovement : MonoBehaviour
private void FinishMovementActions( TileInfo currentTile) private void FinishMovementActions( TileInfo currentTile)
{ {
_playerState.currentTile = currentTile; _playerState.currentTile = currentTile;
_playerState.currentTile.canMove = false;
OnFinishMovement?.Invoke(ActionType.Attack, CharacterState.Idle); OnFinishMovement?.Invoke(ActionType.Attack, CharacterState.Idle);
} }
} }

View File

@ -16,9 +16,9 @@ public class TreesSpawner : MonoBehaviour
public List<GameObject> treePrefabs; public List<GameObject> treePrefabs;
private List<GameObject> ariostTrees = new List<GameObject>(); private List<List<GameObject>> charTrees = new List<List<GameObject>>();
private int requiredAriostTrees; private List<int> requiredCharTrees;
private Queue<GameObject> spawningTrees; private Queue<GameObject> spawningTrees;
@ -30,7 +30,7 @@ public class TreesSpawner : MonoBehaviour
private void PlantTreeOnRandomTile() private void PlantTreeOnRandomTile()
{ {
var treePrefToSpawn = spawningTrees.Dequeue(); /*var treePrefToSpawn = spawningTrees.Dequeue();
int randIndex; int randIndex;
TileInfo tile; TileInfo tile;
@ -59,7 +59,7 @@ public class TreesSpawner : MonoBehaviour
spawningTrees.Enqueue(treePrefToSpawn); spawningTrees.Enqueue(treePrefToSpawn);
PlantTreeOnRandomTile(); PlantTreeOnRandomTile();
return; return;
} } */
//Debug.Log("player pos " + playerPos); //Debug.Log("player pos " + playerPos);
//Debug.Log("tile pos " + tile.tilePosition); //Debug.Log("tile pos " + tile.tilePosition);
@ -70,6 +70,7 @@ public class TreesSpawner : MonoBehaviour
private void CheckForPlanting() private void CheckForPlanting()
{ {
/*foreach()
requiredAriostTrees = Mathf.FloorToInt(treeCoverKoef * TileManagment.ariostTiles.Count); requiredAriostTrees = Mathf.FloorToInt(treeCoverKoef * TileManagment.ariostTiles.Count);
int newTreesForPlanting = requiredAriostTrees - ariostTrees.Count - spawningTrees.Count; int newTreesForPlanting = requiredAriostTrees - ariostTrees.Count - spawningTrees.Count;
//Debug.Log("need to spawn " + newTreesForPlanting); //Debug.Log("need to spawn " + newTreesForPlanting);
@ -78,7 +79,7 @@ public class TreesSpawner : MonoBehaviour
for (int i = 0; i < newTreesForPlanting; i++) for (int i = 0; i < newTreesForPlanting; i++)
{ {
CreatePlantTask(); CreatePlantTask();
} }*/
} }
private void CreatePlantTask() private void CreatePlantTask()

File diff suppressed because one or more lines are too long