Backstory: I’m trying to iterate on Dragon Force, a Sega Saturn game from 1996. Here’s the type of combat I’m trying to recreate: YouTube
So here’s a video of what I’m seeing. A troop will acquire the nearest target and move towards it. However, with ranged attacks, spells, and knock-backs it’s likely they’ll need to constantly be checking to see if there’s a better target for them.
So here’s my code with the caveat that I’m somewhat new to gamedev but completely new to A* pathfinding. The issue I’m trying to solve is everyone randomly stopping but if you could provide insight or point me in a better direction I’d appreciate that a ton as well.
Each troop is using this mobility script:
using UnityEngine;
using Pathfinding;
using static DragonFauxCore;
public class TroopMobility : MonoBehaviour
{
public Transform target;
public string opponent;
private void Start()
{
opponent = gameObject.CompareTag("Player") ? "Enemy" : "Player";
target = GetClosestEnemy(opponent);
gameObject.GetComponent<TroopDestinationSetter>().target = target;
}
private void Update()
{
if (GetClosestEnemy(opponent) != target)
{
target = GetClosestEnemy(opponent);
gameObject.GetComponent<TroopDestinationSetter>().target = target;
Debug.Log(gameObject.name + " updating target to " + target);
}
}
private Transform GetClosestEnemy(string opponent)
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag(opponent);
Transform bestTarget = null;
float closestDistance = Mathf.Infinity;
Vector3 currentPosition = transform.position;
foreach (GameObject enemy in enemies)
{
float distance = Vector3.Distance(enemy.transform.position, currentPosition);
if (distance < closestDistance)
{
closestDistance = distance;
bestTarget = enemy.transform;
}
}
return bestTarget;
}
}
The thought is if their current target
is the same as their bestTarget
then nothing gets pushed to <TroopDestinationSetter>
which is literally just the stock <AIDestinationSetter>
but I’ve added an offset so the troops aren’t trying to stand on top of each other.
namespace Pathfinding
{
public class TroopDestinationSetter : VersionedMonoBehavior
{
. . .
void Update()
{
if (target != null && ai != null) ai.destination = TargetOffset(target);
}
private Vector3 TargetOffset(Transform target)
{
// We want the target destination to be just to the left or
// right of the target, not the target itself.
float offset = (gameObject.transform.position.x > target.transform.position.x) ? .5f : -.5f;
Vector3 offsetTarget = new Vector3(target.transform.position.x + offset, target.transform.position.y, target.transform.position.z);
return offsetTarget;
}
}
}
That’s what I’ve got so far. I’d also love some insight into how to make the troops go around each other to try and focus an enemy from both sides instead of standing in a line but I can keep playing around with that.
Thanks in advance!