Hello, I am trying to make cube enemies swarm a player. However I don’t know where to start, or how to get the cube to follow the player and if it “sees” an obstacle go around it, maybe using ray casts. If possible I would like to keep all code in C#. Please Help and thank you!!

I found that if I use the Navigation utility that Unity has I can add a NavMeshAgent to my enemy, and then by baking the surroundings using the Navigation Window, make the enemy follow the player via its transform.
Link to Unity Tutorial: Here

using UnityEngine;
using System.Collections;

[RequireComponent (typeof(NavMeshAgent))]
public class EnemyMovement : MonoBehaviour
{
    public Transform player;
    NavMeshAgent nav;

    void Awake ()
    {
        player = GameObject.FindGameObjectWithTag ("Player").transform;
        nav = GetComponent <NavMeshAgent> ();
    }

  void Update ()
    {
            nav.SetDestination (player.position);
    }
}

Looks like you want to look into pathfinding. There are many different types, their uses depending on how complicated or ‘smart’ you need or want it, and also depending on the type of terrain or area that the AI needs to navigate. Each have different performance costs of using as well. I’d look into the breadth-first algorithm if you’re just starting out.

If your terrain is flat, it makes things easier to start. You can divide the terrain into ‘tiles’, which can correspond to an array, with locations that are obstacles marked as such in the array. Once you have this information, you can then use an algorithm to find a path between two points in the array. Depending on the algorithm, the path isn’t necessarily the shortest or fastest route or most direct. A breadth-first search would probably be the shortest route in your case.

This person has done a good job of explaining briefly different types of pathfinding algorithms: Path finding algorithms? - Game Development Stack Exchange

Hey,

This is how I’m doing it in my topdown shooter.

Basically:

  1. The enemy casts a Physics.OverlapSphere and checks if any colliders intersect with it within a certain radius i.e. 5 meters.
  2. An array of colliders is returned. I have a layerMask on this Overlapsphere so that the enemy doesn’t hit the colliders on the ground, etc. That would be inefficient.
  3. Being inefficient and explicit, I check if the collider has a tag of player using CompareTag(“Player”).
  4. If this evaluates to true, I make the enemy LookAt() the player, and begin movement using transform.translate in the Vector3.forward direction (move in the direciton the enemy is facing, and he’s already facing the player).

Here is the big example code you can sift through:

using UnityEngine;
using System.Collections;

public class AI_FollowController : MonoBehaviour {

    Collider[] playersInRange;
    Collider[] playersToAttack;
    public GameObject attackSphereContainer;
    private SphereCollider attackSphere;
    public float searchRadius = 20f;
    public LayerMask playerOnly;
    public LayerMask wallBlocks;
    Animator anim;
    EnemyAudioManager __eam;

    public float enemySpeed = 10;
    public float enemyChaseRange = 20;
    public float timeSinceLastAttack = 0;
    public bool isChasing = false;
    public bool isRunning = false;
    public bool isDead = false;
    public bool isAttacking = false;

    // Use this for initialization
    void Start () {

        __eam = GetComponent<EnemyAudioManager>();
        attackSphere = attackSphereContainer.GetComponent<SphereCollider>();

        anim = GetComponent<Animator>();
        StartCoroutine(playerCheck());
	
	}
	
	// Update is called once per frame
	void Update () {

        timeSinceLastAttack += Time.deltaTime;

        if (isChasing)
        {
            chasePlayer(playersInRange[0]);
        }

	}

    public IEnumerator playerCheck()
    {

        //print("checking for players...");

        playersInRange = Physics.OverlapSphere(transform.position, searchRadius, playerOnly);

        if(playersInRange.Length == 0)
        {
            //print("no players found");
            isChasing = false;
            anim.SetBool("isChasing", false);
        }
        else
        {
            //print("player<s> found, generating list");
            int i = 0;
            while (i < playersInRange.Length)
            {
                float dAway = Vector3.Magnitude(transform.position - playersInRange*.transform.position);*

RaycastHit wallCheck;
if(Physics.Linecast(transform.position, playersInRange*.transform.position, out wallCheck, wallBlocks))*
{
//print(“player in range, no line of sight”);
}
else if (dAway < enemyChaseRange)
{
isChasing = true;
//chasePlayer(playersInRange*);*
}

i++;
}
}

yield return new WaitForSeconds(0.15f);

StartCoroutine(playerCheck());

}

public void chasePlayer(Collider player)
{
if (isDead)
{
isAttacking = false;
}
else
{
float dAway = Vector3.Magnitude(transform.position - player.transform.position);
Vector3 playerPos = player.transform.position + Vector3.up * transform.position.y;

transform.LookAt(playerPos);
transform.Translate(Vector3.forward * enemySpeed * Time.deltaTime);

if (dAway < enemyChaseRange && !isRunning)
{
if (dAway < 2.0f)
{
anim.SetBool(“isAttacking”, true);
anim.SetBool(“isChasing”, true);
}
else
{
anim.SetBool(“isAttacking”, false);
anim.SetBool(“isChasing”, true);
}
}
else if (dAway < enemyChaseRange && isRunning == true)
{

if (dAway < 2.0f)
{
anim.SetBool(“isAttacking”, true);
anim.SetBool(“isRunning”, true);
}
else
{
anim.SetBool(“isAttacking”, false);
anim.SetBool(“isRunning”, true);
}

}
}

}
}
You should use OnDrawGizmos function as a good way to check how big your aggro sphere is in the Scene view.

Here’s a real simple enemy follow script.

	public Transform Player;
	public float speed = 2f;
	private float minDistance = 0.2f;
	private float range;
	void Update ()
	{
		Player = GameObject.FindWithTag ("Player").transform;
		range = Vector2.Distance(transform.position, Player.position);

		if (range > minDistance)
		{
			Debug.Log(range);
			Player = GameObject.FindWithTag ("Player").transform;
			transform.position = Vector2.MoveTowards(transform.position, Player.position, speed * Time.deltaTime);
		}
	}
}