Day 6 of Getting Started with Unity: Enemy AI, Map Randomly Generated
\beautiful/
This article describes how to make enemy tanks attack smarter and how to generate random maps
Writing the enemy AI
In the plan, the enemy (silver tank) appears at the top of the game, and through a series of moves, it finally reaches the base and knocks down the heart
. So the enemy moves automatically without human intervention. In order to realize this design, we modified the move
method of the original player
script:
1 | // enemy movement |
The current AI looks stupid and often hits the wall, there should be an update next day
Thinking of the bosses of soul games, they use different skills by identifying the distance and position between the player and themselves, and even feinting tricks. It makes people unpredictable and think that designing an intelligent boss is a lot of work.
map generation
Create a new GameObject
in hierarchy
and name it MapCreation
. After writing, you can randomly generate maps and enemies. Only MapCreation
is left in hierarchy
, everything else can be deleted, it looks very neat.
Here is a generated map:
When you don’t know the exact coordinates, you can move the player’s tank and find the critical point in the Game
interface. Here is (10,8), (10,-8), (-10,8), (-10,-8)
.
The generation of the map is divided into:
- Fixed base and brick wall generation next to base
- Random Brick Wall, Iron Wall, Grass, River Generation
- Fixed player and enemy spawns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapCreation : MonoBehaviour
{
//The array used to decorate the objects needed to initialize the map
//0. Base, 1. Wall, 2. Obstacle, 3. Birth Effect, 4. River, 5. Grass, 6. Air Wall
//Drag into the GameObject in turn in the "hierarchy" interface
public GameObject[] item;
//Add all generated positions to the list
//Note that the L of List should be capitalized
private List<Vector3> itemPoistionList = new List<Vector3>();
//Instantiate in awake(), let the map be generated before all other objects
private void Awake(){
//Instantiate the base
//Quaternion.identity: The currently instantiated object has no rotation angle, what is the rotation angle of the prefab, and how much is obtained by instantiation
CreateItem(item[0], new Vector3(0,-8,0), Quaternion.identity);
// Enclose the base with walls
CreateItem(item[1], new Vector3(-1,-8,0), Quaternion.identity);
CreateItem(item[1], new Vector3(1,-8,0), Quaternion.identity);
//The lazy builds three brick walls with a for loop
for (int i = -1; i<2; i++){
CreateItem(item[1], new Vector3(i,-7,0), Quaternion.identity);
}
//Instantiate the air wall to prevent tanks from running around and recover bullets
for (int i = -11; i<12; i++){
CreateItem(item[6], new Vector3(i,9,0), Quaternion.identity);}
for (int i = -11; i<12; i++){
CreateItem(item[6], new Vector3(i,-9,0), Quaternion.identity);}
for (int i = -8; i<9; i++){
CreateItem(item[6], new Vector3(-11,i,0), Quaternion.identity);}
for (int i = -8; i<9; i++){
CreateItem(item[6], new Vector3(11,i,0), Quaternion.identity);}
//Initialize the player
GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);
//Get the component and set the create player to true, that is, create the player
go.GetComponent<Born>().createPlayer = true;
//spawn enemy
CreateItem(item[3], new Vector3(-10, 8, 0), Quaternion.identity);
CreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity);
CreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);
//Repeat call (method name, call this method after a delay of a few seconds, how often to call it)
InvokeRepeating("CreateEnemy", 4, 5);
//Instantiate the map
for(int i = 0; i<60;i++){
CreateItem(item[1], createRandomPosition(), Quaternion.identity);
}
for(int i = 0; i<20;i++){
CreateItem(item[2], createRandomPosition(), Quaternion.identity);
}
for(int i = 0; i<20;i++){
CreateItem(item[4], createRandomPosition(), Quaternion.identity);
}
for(int i = 0; i<20;i++){
CreateItem(item[5], createRandomPosition(), Quaternion.identity);
}
}
//Let instantiated objects appear as components of MapCreation, not scattered on Hierarchy
private void CreateItem(GameObject createGameObject,Vector3 createPosition, Quaternion createRotation){
// instantiate the object
GameObject itemGo = Instantiate(createGameObject, createPosition,createRotation);
//Set MapCreation as the parent layer
itemGo.transform.SetParent(gameObject.transform);
//Add to the location list
itemPoistionList.Add(createPosition);
}
// method to generate random positions
public Vector3 createRandomPosition(){
//Do not generate x=-10 and 10 columns; y=-8 and 8 lines, otherwise the tank will be stuck (small probability)
while (true)
{//The Random.Range() method of type int includes the first number, excluding the second number
Vector3 createPosition = new Vector3(Random.Range(-9,10), Random.Range(-7,8), 0);
//If this position has not been generated, return an available random position and jump out of the loop
if(hasThePosition(createPosition) == false){
return createPosition;
}
}
}
// Determine if this location exists in the location list
private bool hasThePosition(Vector3 createPos){
//The length of the list is represented by .Count
for (int i=0; i < itemPoistionList.Count; i++)
{
if (createPos == itemPoistionList[i]){
return true;
}
}
//If there is no same position after traversing, return false to indicate that a new position can be established
return false;
}
// method to spawn enemies
private void CreateEnemy(){
// Enemy randomly generated position
int num = Random.Range(0,3);
Vector3 enemyPos = new Vector3();
if (num == 0){
enemyPos = new Vector3(-10, 8, 0);
}
else if (num == 1){
enemyPos = new Vector3(0, 8, 0);
}
else{
enemyPos = new Vector3(10, 8, 0);
}
CreateItem(item[3], enemyPos, Quaternion.identity);
}
}
There is still the AI update, and the UI and game judgments are about to be completed.