TurnBasedStrategyCourse/Assets/Scripts/Actions/MoveAction.cs

93 lines
4.1 KiB
C#

using System;
using System.Collections.Generic;
using Grid;
using UnityEngine;
using UnityEngine.Serialization;
namespace Actions {
public class MoveAction : BaseAction {
private const float moveSpeed = 4f;
private const float rotationSpeed = 10f;
private const float stoppingDistance = 0.1f;
private const int pathfindingDistanceMultiplier = 10;
[FormerlySerializedAs("MaxMoveDistance")] [SerializeField]
private int maxMoveDistance = 4;
private int currentPositionIndex;
private List<Vector3> PositionList { get; set; }
protected override void Awake() {
base.Awake();
ActionName = "Move";
}
private void Update() {
if (!IsActive) return;
Vector3 targetPosition = PositionList[currentPositionIndex];
Vector3 moveDirection = (targetPosition - Unit.GetWorldPosition()).normalized;
transform.forward = Vector3.Lerp(transform.forward, moveDirection, rotationSpeed * Time.deltaTime); //Rotate towards targetPosition
if (Vector3.Distance(targetPosition, Unit.GetWorldPosition()) > stoppingDistance) {
//Move towards targetPosition
transform.position += moveSpeed * Time.deltaTime * moveDirection;
}
else {
currentPositionIndex++;
if (currentPositionIndex < PositionList.Count) return;
OnStopMoving?.Invoke(this, EventArgs.Empty);
ActionComplete();
}
}
public event EventHandler OnStartMoving;
public event EventHandler OnStopMoving;
public override List<GridPosition> GetValidActionGridPositionList() {
List<GridPosition> validGridPositionList = new();
GridPosition unitGridPosition = Unit.GridPosition;
for (int xPosition = -maxMoveDistance; xPosition <= maxMoveDistance; xPosition++) {
for (int zPosition = -maxMoveDistance; zPosition <= maxMoveDistance; zPosition++) {
for (int floor = -maxMoveDistance; floor < maxMoveDistance; floor++) {
GridPosition offsetGridPosition = new(xPosition, zPosition, floor);
GridPosition testGridPosition = unitGridPosition + offsetGridPosition;
if (!LevelGrid.Instance.IsValidGridPosition(testGridPosition)) continue; //Only return valid grid positions
if (unitGridPosition == testGridPosition) continue; //Same grid position where the unit is already at
if (LevelGrid.Instance.HasAnyUnitOnGridPosition(testGridPosition)) continue; //Grid position already occopied with anther unit
if (!Pathfinding.Instance.IsWalkableGridPosition(testGridPosition)) continue; //Obstacle on path
if (!Pathfinding.Instance.HasPath(unitGridPosition, testGridPosition)) continue; //No path available
if (Pathfinding.Instance.GetPathLength(unitGridPosition, testGridPosition) > maxMoveDistance * pathfindingDistanceMultiplier) continue; //Pathlength is to long
validGridPositionList.Add(testGridPosition);
}
}
}
return validGridPositionList;
}
public override void TakeAction(GridPosition gridPosition, Action onMoveCompleted) {
List<GridPosition> pathGridPositionList = Pathfinding.Instance.FindPath(Unit.GridPosition, gridPosition, out _);
currentPositionIndex = 0;
PositionList = new();
foreach (GridPosition pathGridPosition in pathGridPositionList) {
PositionList.Add(LevelGrid.Instance.GetWorldPosition(pathGridPosition));
}
OnStartMoving?.Invoke(this, EventArgs.Empty);
ActionStart(onMoveCompleted);
}
protected override EnemyAIAction GetEnemyAIAction(GridPosition gridPosition) {
int targetCountAtGridPosition = Unit.GetAction<ShootAction>().GetTargetCountAtPosition(gridPosition);
return new(gridPosition, targetCountAtGridPosition * 10);
}
}
}