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))]
public class AnimationController : MonoBehaviour
{
public Animator characterAnimator;
private Animator _characterAnimator;
private PlayerState _playerState;
private void Start()
{
_playerState = GetComponent<PlayerState>();
_characterAnimator = GetComponentInChildren<Animator>();
_playerState.OnCharStateChanged += SetNewStateAnimation;
}
@ -36,7 +36,7 @@ public class AnimationController : MonoBehaviour
}
if (activationTrigger != "")
{
characterAnimator.SetTrigger(activationTrigger);
_characterAnimator.SetTrigger(activationTrigger);
}
}

View File

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

View File

@ -2,12 +2,10 @@ using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class CustomInput : MonoBehaviour
{
public static Vector2 leftInput, rightInput;
public static float rightRegistrationDeadZone = 0.3f;
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

@ -14,9 +14,7 @@ public class PlayerActionManager : MonoBehaviour
public Action OnLostTarget;
private PlayerState _playerState;
private PlayerAction _currentAction;
private IEnumerator _currentCoroutine;
private PlayerAction _currentAction;
private TileInfo _target;
@ -24,7 +22,7 @@ public class PlayerActionManager : MonoBehaviour
private void Awake()
{
_playerState = FindObjectOfType<PlayerState>();
_playerState = GetComponent<PlayerState>();
_playerState.OnActionChanged += SetNewCurrentAction;
CustomInput.OnTouchDown += StartTargeting;
@ -86,8 +84,7 @@ public class PlayerActionManager : MonoBehaviour
{
OnLostTarget?.Invoke();
//StopCoroutine(_currentCoroutine);
StopAllCoroutines();
_currentCoroutine = null;
StopAllCoroutines();
_target = null;
}

View File

@ -10,6 +10,7 @@ public class PlayerState : MonoBehaviour
public CharacterState currentState;
public TileOwner ownerIndex = TileOwner.Ariost;
public ActionType currentAction = ActionType.Attack;
public ControlType controlType = ControlType.Player;
public TileInfo currentTile;
@ -94,7 +95,7 @@ public class PlayerState : MonoBehaviour
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,
Build,
}
public enum ControlType
{
Player,
AI
}

View File

@ -17,7 +17,7 @@ public class TileInfo : MonoBehaviour
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 static List<TileInfo> levelTiles = new List<TileInfo>();
public static List<TileInfo> ariostTiles = new List<TileInfo>();
public List<Material> tileMaterials;
public static List<List<TileInfo>> charTiles = new List<List<TileInfo>>();
public List<Material> tileMaterials;
//public List<TileInfo> pathTiles = new List<TileInfo>();
public static float tileOffset;
@ -18,6 +20,7 @@ public class TileManagment : MonoBehaviour
private void Awake()
{
InitCharTiles();
for (int i = 0; i < transform.childCount; i++)
{
var tile = transform.GetChild(i).GetComponent<TileInfo>();
@ -25,24 +28,31 @@ public class TileManagment : MonoBehaviour
{
levelTiles.Add(tile);
SetTileStartParams(tile);
if (tile.tileOwnerIndex == TileOwner.Ariost)
{
ariostTiles.Add(tile);
}
charTiles[(int)tile.tileOwnerIndex].Add(tile);
}
}
tileOffset = Vector3.Distance(levelTiles[0].tilePosition, levelTiles[3].tilePosition);
basicDirections = GetBasicDirections(BASIC_DIRECTIONS);
}
}
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()
{
//Debug.Log("We have "+ levelTiles.Count + " tiles on this level");
//Debug.Log("Tiles offset "+ _tilesOffset +" units");
//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)
{
Debug.LogError("You need to set tile materials to TileManagment");
@ -62,12 +72,12 @@ public class TileManagment : MonoBehaviour
tile.tileOwnerIndex = ownerIndex;
tile.GetComponent<Renderer>().material = tileMaterials[(int)tile.tileOwnerIndex];
ariostTiles.Add(tile);
charTiles[(int)ownerIndex].Add(tile);
//Debug.Log(GetOtherTiles(tile).Count);
CheckSurroundedTiles(levelTiles, ownerIndex, tile);
//CheckSurroundedTiles(levelTiles, ownerIndex, tile);
//Debug.Log("Captured " + tile.name);
}
}
public static void AssignBuildingToTile(TileInfo tile, GameObject building)
{
@ -84,23 +94,23 @@ public class TileManagment : MonoBehaviour
if (Vector3.Distance(position, tile.tilePosition) < Vector3.Distance(position, resultTile.tilePosition))
{
resultTile = tile;
}
}
}
if (Vector3.Distance(position, resultTile.tilePosition) > tileOffset/2)
if (Vector3.Distance(position, resultTile.tilePosition) > tileOffset / 2)
{
return null;
}
else
else
{
return resultTile;
}
}
}
public static TileInfo GetTile(Vector3 currentTilePosition, Vector3 direction, float distance)
{
direction = direction.normalized;
distance = distance - 0.1f;
Vector3 tilePos = currentTilePosition + (direction * distance*tileOffset);
distance = distance - 0.1f;
Vector3 tilePos = currentTilePosition + (direction * distance * tileOffset);
return GetTile(tilePos);
}
@ -110,7 +120,7 @@ public class TileManagment : MonoBehaviour
//int notMyTiles = 0;
foreach (Vector3 dir in basicDirections)
{
var tile = GetTile(currentTile.tilePosition + dir * TileManagment.tileOffset);
var tile = GetTile(currentTile.tilePosition + dir * tileOffset);
if (tile)
{
if (tile.tileOwnerIndex != ownerIndex)
@ -124,6 +134,31 @@ public class TileManagment : MonoBehaviour
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)
{
Vector3[] tempArr = new Vector3[directionsAmount];
@ -138,10 +173,10 @@ public class TileManagment : MonoBehaviour
public static void CheckSurroundedTiles(List<TileInfo> tiles, TileOwner ownerIndex, TileInfo startTile)
{
foreach (TileInfo tile in tiles)
/*foreach (TileInfo tile in tiles)
{
tile.isChecked = false;
}
}*/
List<TileInfo> firstAdjacentTiles = GetOtherTiles(startTile, ownerIndex);
foreach (TileInfo tile in firstAdjacentTiles)
{
@ -178,7 +213,7 @@ public class TileManagment : MonoBehaviour
}
surroundedTiles.Add(tile);
tile.isChecked = true;
//tile.isChecked = true;
var adjacentTiles = GetOtherTiles(tile, ownerIndex);
//Debug.Log("second tiles "+ adjacentTiles.Count);

View File

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

View File

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

File diff suppressed because one or more lines are too long