In game development, enemy AI (Artificial Intelligence) is an important element that enhances the challenge and immersion of the game. In this course, we will explain in detail how to implement simple AI for enemy characters in Unity 2D games, as well as how to set up tracking and attacking behaviors. This course is useful for beginners to intermediate developers and aims to aid understanding through practical exercises.
1. Setting Up the Project
First, create a new 2D project in Unity. Set the project name to “EnemyAIExample” and complete the setup. Select the necessary 2D template by default.
1.1 Initial Setup
Once the project is created, use 2D sprites to create the map, player character, and enemy character. Import the appropriate sprites to store them in the Assets folder.
1.2 Placing Player and Enemy Characters
Create a simple map in the scene and place the player and enemy character sprites. At this point, set the player’s name to “Player” and the enemy character’s name to “Enemy”.
2. Understanding Basic Enemy AI
Enemy AI can be broadly divided into two behaviors: Chasing and Attacking. Chasing includes the enemy detecting and following the player, while Attacking includes the enemy attacking the player who comes close.
2.1 Managing AI States
It is important to define states to manage AI behavior. The following states are defined:
- Idle: Waiting state
- Chase: State of tracking the player
- Attack: State of attacking the player
3. Writing Enemy Character Script
We will create a C# script to implement the AI logic for the enemy character. Create a script named EnemyAI.cs and write the following code.
using UnityEngine;
public class EnemyAI : MonoBehaviour {
public float moveSpeed = 2f; // Enemy movement speed
public float chaseRange = 5f; // Tracking range
public float attackRange = 1f; // Attack range
private Transform player; // Player's Transform
private Rigidbody2D rb; // Enemy character's Rigidbody2D
private enum State { Idle, Chase, Attack } // States of the enemy AI
private State currentState = State.Idle; // Initial state
void Start() {
player = GameObject.FindWithTag("Player").transform; // Find the player
rb = GetComponent<Rigidbody2D>(); // Get the Rigidbody2D component
}
void Update() {
// Behavior based on current state
switch (currentState) {
case State.Idle:
IdleBehavior();
break;
case State.Chase:
ChaseBehavior();
break;
case State.Attack:
AttackBehavior();
break;
}
}
private void IdleBehavior() {
// Calculate distance to the player
float distance = Vector2.Distance(transform.position, player.position);
if (distance < chaseRange) {
currentState = State.Chase; // Switch to chasing state
}
}
private void ChaseBehavior() {
float distance = Vector2.Distance(transform.position, player.position);
// Move towards the player
if (distance > attackRange) {
Vector2 direction = (player.position - transform.position).normalized;
rb.MovePosition(rb.position + direction * moveSpeed * Time.deltaTime);
} else {
currentState = State.Attack; // Switch to attacking state
}
if (distance > chaseRange) {
currentState = State.Idle; // Switch to idle state
}
}
private void AttackBehavior() {
// Implement attack logic
// You can add code here to deal damage to the player
Debug.Log("Attacking the player!");
currentState = State.Idle; // Return to idle state by default
}
}
4. Explanation of Enemy Character’s AI Logic
We will explain the main functionalities in the code one by one.
4.1 State Management
States are managed using enum State
, and the current state is defined by the currentState
variable. The current state behavior is determined in Unity’s Update
method.
4.2 Tracking the Player
State transitions are made based on distance calculations to the player. In IdleBehavior()
, the distance to the player is measured, which decides the transition to ChaseBehavior()
.
4.3 Implementing Attacks
When the enemy approaches the player, it transitions to the attacking state and executes AttackBehavior()
. In this state, logic to deal damage to the player can be added. Typically, attack animations or effects added recently are executed.
5. Setting Enemy Character Position
After the enemy character is placed in the scene, set the Gravity Scale
value of the enemy’s Rigidbody2D
component to 0 so that it is not affected by gravity. The enemy can move, and layers can be adjusted to prevent it from colliding with the player.
6. Code Optimization and Expansion
If you want to add more functionalities to the basic code above, there are various ways to do so, but you can develop the basic AI patterns and behavior logic further. For example, you could set an attack cooldown to avoid continuous attacking or apply animations for each state.
6.1 Setting Attack Cooldown
private float attackCooldown = 1f; // Attack cooldown timer
private float lastAttackTime = 0f;
private void AttackBehavior() {
float distance = Vector2.Distance(transform.position, player.position);
if (distance < attackRange && Time.time - lastAttackTime > attackCooldown) {
Debug.Log("Attacking the player!");
// You can add code here to deal damage to the player
lastAttackTime = Time.time; // Update the last attack time
} else {
currentState = State.Idle; // Return to idle state by default
}
}
6.2 Adding Animations
Using Unity’s animation system, you can play appropriate animations when the enemy is chasing and attacking. Add an animator component to the enemy character and create and set animations for each state. You can add code that calls the appropriate animation trigger based on state transitions.
7. Conclusion
In this tutorial, we learned how to implement simple enemy AI using Unity. We created basic actions for the enemy character to track and attack the player. Based on this foundation, you can design a variety of AI behaviors and apply them to your game. Since AI can add more challenges and excitement, unleash your creativity!
8. Additional Resources
Thank you! I hope this course helps you, and I wish you great success in your game development journey.