-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathautomaton.html
More file actions
238 lines (204 loc) · 8.64 KB
/
Copy pathautomaton.html
File metadata and controls
238 lines (204 loc) · 8.64 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
<!DOCTYPE HTML>
<!--
Stellar by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html>
<head>
<title>Automaton</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="assets/css/main.css" />
<link rel="stylesheet" type="text/css" href="prism.css">
<script src="prism.js"></script>
<noscript><link rel="stylesheet" href="assets/css/noscript.css" /></noscript>
</head>
<body class="is-preload">
<!-- Wrapper -->
<div id="wrapper">
<!-- Header -->
<!-- Nav -->
<nav class="new-nav">
<ul>
<li><a href="index.html#intro" class="active">About Me</a></li>
<li><a href="index.html#first">Work Experience</a></li>
<li><a href="index.html#second">Projects</a></li>
<li><a href="#footer">Contact Information</a></li>
</ul>
</nav>
<!-- Main -->
<div class="project-page-background">
<!-- Content -->
<section class="main">
<h1 class="project-page-title">Automaton - Unity/C#</h1>
<h2 class="project-page-subtitle">Gameplay</h2>
<iframe class="image vid"
src="https://www.youtube.com/embed/6i61CWoGUeo">
</iframe>
<h2 class="project-page-subtitle">Overview</h2>
<ul class="project-page-subtitle">
<li>Designed and implemented an enemy AI using a behavior tree with behaviors such as chasing, killing, patrolling, and
stalking</li>
<li>Designed and implemented an AI director script in C# that gives hints to the enemy AI about the location of the player</li>
</ul>
<h2 class="project-page-subtitle">Code Snippets</h2>
<button class="collapsible">AI Director Class</button>
<!-- Code Snippet -->
<div class="content" style="display: none;"><pre class="line-numbers"><code class="language-clike">public class Director : MonoBehaviour
{
// Declaring and Initializing variables
public GameObject player; // Reference to the player
public GameObject stalker; // Reference to the stalker
public List<GameObject> defAreaWaypoints; // List of the default waypoints that the stalker will follow
// Called when the script is instantiated
private void Start()
{
// Starts the enemy on the default path
stalker.GetComponent<StalkerEnemy>().waypoints = defAreaWaypoints;
Debug.Log("defArea: " + defAreaWaypoints[0]);
Debug.Log("Enemy Waypoints" + stalker.GetComponent<StalkerEnemy>().waypoints[0]);
// Starts the hint routine
StartCoroutine(GiveHintRoutine());
}
// Coroutine for given the stalker a hint
private IEnumerator GiveHintRoutine()
{
// Defines the amount of time between coroutine execution
WaitForSeconds waitTime = new WaitForSeconds(15f);
// Continuously runs the hint given function
while (true)
{
yield return waitTime;
GiveHint();
}
}
// Function that gives hint to the enemy
private void GiveHint()
{
stalker.GetComponent<StalkerEnemy>().waypoints = player.GetComponent<PlayerAreaTracker>().areaEntered.transform.parent.GetComponent<CollisionDetection>().waypointsList;
Debug.Log(player.GetComponent<PlayerAreaTracker>().areaEntered.transform.parent.GetComponent<CollisionDetection>().waypointsList[0]);
}
}</code></pre></div>
<button class="collapsible">AI Patrolling Behavior</button>
<!-- Code Snippet -->
<div class="content" style="display: none;"><pre class="line-numbers"><code class="language-clike">public class TaskPatrol : Action
{
// Declaring and Initializing variables
[SerializeField]
private GameObject enemy; // Reference to the enemy game object
[SerializeField]
private float speed; // Patrolling speed of the enemy
private int currentWaypointIndex = 0; // Index of the waypoint currently followed by the enemy
// Task executed by the behavior tree
public override TaskStatus OnUpdate()
{
// Only executute when condition is met
if (!enemy.GetComponent<StalkerEnemy>().isPatrol)
{
return TaskStatus.Failure;
}
// Animate patrolling
enemy.GetComponent<Animator>().SetBool("isRunning", false);
enemy.GetComponent<Animator>().SetBool("isPatrolling", true);
// Gets the list of waypoints currently followed by the stalker
List<GameObject> waypoints = enemy.GetComponent<StalkerEnemy>().waypoints;
// Makes sure the enemy is able to move and the speed is slowed
enemy.GetComponent<NavMeshAgent>().isStopped = false;
enemy.GetComponent<NavMeshAgent>().speed = speed;
// Set the general viewing radius
enemy.GetComponent<StalkerViewing>().generalViewRadius = 14;
enemy.GetComponent<StalkerViewing>().generalViewAngle = 210;
// Resets the waypoint index if it is over the length of the waypoint list
if (currentWaypointIndex == int.MaxValue)
{
currentWaypointIndex = 0;
}
// Gets the current waypoint that the enemy is following
GameObject wp = waypoints[currentWaypointIndex % waypoints.Count];
//Debug.Log(waypoints[currentWaypointIndex % waypoints.Count]);
// The enemy is close enough to the waypoint
if (Vector3.Distance(enemy.transform.position, wp.transform.position) < 1.5f)
{
currentWaypointIndex += 1;
}
// Enemy follows the current waypoint
else
{
enemy.GetComponent<NavMeshAgent>().destination = wp.transform.position;
}
return TaskStatus.Success;
}
}</code></pre></div>
<button class="collapsible">AI Chase Behavior</button>
<!-- Code Snippet -->
<div class="content" style="display: none;"><pre class="line-numbers"><code class="language-clike">public class TaskChase : Action
{
// Declaring and Initializing variables
[SerializeField]
private GameObject enemy; // Reference to the enemy game object
[SerializeField]
private GameObject player; // Reference to the player game object
// Task executed by the behavior tree
public override TaskStatus OnUpdate()
{
// Update the last player position
enemy.GetComponent<StalkerEnemy>().lastPlayerPosition = player.transform.position;
// Enemy can see the player
if (enemy.GetComponent<StalkerViewing>().isPlayerGeneralSeen)
{
// Animates running
enemy.GetComponent<Animator>().SetBool("isPatrolling", false);
enemy.GetComponent<Animator>().SetBool("isRunning", true);
// Sets multiple attributes of the navmesh for chasing the player
enemy.GetComponent<NavMeshAgent>().speed = 3.0f;
enemy.GetComponent<NavMeshAgent>().isStopped = false;
enemy.GetComponent<NavMeshAgent>().SetDestination(player.transform.position);
// Increase the general viewing radius
enemy.GetComponent<StalkerViewing>().generalViewRadius = 17;
// Increase the general view radius
enemy.GetComponent<StalkerViewing>().generalViewAngle = 250;
return TaskStatus.Success;
}
else
{
enemy.GetComponent<StalkerEnemy>().EnemyStatePatrol();
return TaskStatus.Failure;
}
}
}</code></pre></div>
<button class="collapsible">AI Behavior Tree</button>
<!-- Code Snippet -->
<div class="content" style="display: none;">
<img src="AutomatonAI.PNG" class="image fit">
</div>
</section>
</div>
<!-- Footer -->
<footer id="footer">
<section>
<h2>Contact information</h2>
<dl class="alt">
<dt>Linkedin</dt>
<a href="https://www.linkedin.com/in/dani-amir/"><dd>https://www.linkedin.com/in/dani-amir/</dd></a>
<dt>Email</dt>
<dd><a href="#">daniamir2001@yahoo.com</a></dd>
</dl>
<ul class="icons">
<li><a href="https://github.com/Htmlpro19/" class="icon brands fa-github alt"><span class="label">GitHub</span></a></li>
<li><a href="https://www.linkedin.com/in/dani-amir/" class="icon brands fa-linkedin alt"><span class="label">Linkedin</span></a></li>
</ul>
</section>
<p class="copyright">© Dani Amir. Design: <a href="https://html5up.net">HTML5 UP</a>.</p>
</footer>
</div>
<!-- Scripts -->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/jquery.scrollex.min.js"></script>
<script src="assets/js/jquery.scrolly.min.js"></script>
<script src="assets/js/browser.min.js"></script>
<script src="assets/js/breakpoints.min.js"></script>
<script src="assets/js/util.js"></script>
<script src="assets/js/main.js"></script>
</body>
</html>