Make Guard AI look for Coin

Coin Distraction Part 2

Tristan Engel
3 min readSep 27, 2021

--

Today we made our AI look for our tossed coin then return to their patrols.

Player Script

To do this we added a coin toss function to our Player script. This will get all gameobjects with the tag Guard1. With a foreach loop each guard will be given the coin position and a public method from the guard ai script will be called.

void SendAIToCoinSpot(Vector3 coinPos)
{
GameObject[] Guards = GameObject.FindGameObjectsWithTag(“Guard1”);
foreach (GameObject guard in Guards)
{
guard.GetComponent<GuardAI>().CheckForCoin(coinPos);
}
}
Sped up scene view

Guard AI Script

The most relevant parts are in bold. Basically when the public method to search for the coin is called we use a bool to prevent the rest of the code to change the destination. Then we use a separate coroutine to make them search at the coin position. Finally we send the guard back to their last waypoint.
The coin can be tossed at anytime during the script hence we added lines of codes to get the animator to function properly. Just as always in programming there are many ways to solve the same problem. This may not be the prettiest code, but it’s working for the different types of guards.

public class GuardAI : MonoBehaviour
{
//handle
private NavMeshAgent _agent;
public List<Transform> waypoints;
private Animator _animator;

//var
private int currentTarget = 0;
private bool _isReverse = false;
private bool _targetReached = false;
private bool _coinSearching = false;

//config
private float _waitToMoveMin = 2f;
private float _waitToMoveMax = 5f;

void Start ()
{
_agent = GetComponent<NavMeshAgent>();
_animator = GetComponent<Animator>();

_animator.SetBool("Walk", true);
_agent.SetDestination(waypoints[currentTarget].position);
}

void Update ()
{
if (waypoints.Count > 0 && waypoints[currentTarget] != null)
{
float distance = Vector3.Distance(transform.position, _agent.destination);
if (distance < 2.5f && _targetReached == false)
{
_targetReached = true;

if (_coinSearching == true)
{
StartCoroutine(SearchForCoin());
}

else if (currentTarget >= waypoints.Count - 1)
{
_isReverse = true;
StartCoroutine(WaitBeforeMoving());
}
else if (currentTarget <= 0)
{
_isReverse = false;
StartCoroutine(WaitBeforeMoving());
}
else
{
ChangeWaypoint();
}
}
}
}

void ChangeWaypoint()
{
if (_coinSearching == false)
{
_targetReached = false;

if (waypoints.Count != 1)
{
if (_isReverse == true)
{
currentTarget--;
}
else if (_isReverse == false)
{
currentTarget++;
}
_agent.SetDestination(waypoints[currentTarget].position);
_animator.SetBool("Walk", true);
}
}
}

IEnumerator WaitBeforeMoving()
{
_animator.SetBool("Walk", false);
yield return new WaitForSeconds(Random.Range(_waitToMoveMin, _waitToMoveMax));
ChangeWaypoint();
}

public void CheckForCoin(Vector3 CoinPos)
{
_agent.SetDestination(CoinPos);
_animator.SetBool("Walk", true);
_coinSearching = true;
_targetReached = false;
}

IEnumerator SearchForCoin()
{
_animator.SetBool("Walk", false);
yield return new WaitForSeconds(Random.Range(_waitToMoveMin, _waitToMoveMax));

_animator.SetBool("Walk", true);
_coinSearching = false;
_targetReached = false;
if (waypoints[currentTarget] != null)
{
_agent.SetDestination(waypoints[currentTarget].position);
}
else
{
_agent.SetDestination(waypoints[0].position);
}
}
}

--

--

Tristan Engel

Aspiring developer that’s self-learning Unity & C# to transition to a career with Unity. I got a passion for creating interactive experiences.